/*
 * Copyright 2016 The Bazel Authors. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.google.idea.blaze.base.vcs.git;

import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.idea.blaze.base.async.process.ExternalTask;
import com.google.idea.blaze.base.io.FileAttributeProvider;
import com.google.idea.blaze.base.model.primitives.WorkspacePath;
import com.google.idea.blaze.base.model.primitives.WorkspaceRoot;
import com.google.idea.blaze.base.scope.BlazeContext;
import com.google.idea.blaze.base.settings.Blaze.BuildSystem;
import com.google.idea.blaze.base.sync.workspace.WorkingSet;
import com.google.idea.blaze.base.vcs.BlazeVcsHandler;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import java.io.ByteArrayOutputStream;
import java.io.File;
import javax.annotation.Nullable;

/** Vcs diff provider for git */
public class GitBlazeVcsHandler implements BlazeVcsHandler {

  private static final Logger logger = Logger.getInstance(GitBlazeVcsHandler.class);

  @Override
  public String getVcsName() {
    return "git";
  }

  @Override
  public boolean handlesProject(BuildSystem buildSystem, WorkspaceRoot workspaceRoot) {
    return buildSystem == BuildSystem.Bazel
        && isGitRepository(workspaceRoot)
        && tracksRemote(workspaceRoot);
  }

  @Override
  public ListenableFuture<WorkingSet> getWorkingSet(
      Project project,
      BlazeContext context,
      WorkspaceRoot workspaceRoot,
      ListeningExecutorService executor) {
    return executor.submit(
        () -> {
          String upstreamSha = getUpstreamSha(workspaceRoot, false);
          if (upstreamSha == null) {
            return null;
          }
          return GitWorkingSetProvider.calculateWorkingSet(workspaceRoot, upstreamSha, context);
        });
  }

  @Nullable
  @Override
  public BlazeVcsSyncHandler createSyncHandler(Project project, WorkspaceRoot workspaceRoot) {
    return null;
  }

  @Override
  public ListenableFuture<String> getUpstreamContent(
      Project project,
      BlazeContext context,
      WorkspaceRoot workspaceRoot,
      WorkspacePath path,
      ListeningExecutorService executor) {
    return executor.submit(() -> getGitUpstreamContent(workspaceRoot, path));
  }

  private static String getGitUpstreamContent(WorkspaceRoot workspaceRoot, WorkspacePath path) {
    String upstreamSha = getUpstreamSha(workspaceRoot, false);
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    ExternalTask.builder(workspaceRoot)
        .args(
            "git",
            "show",
            // Normally "For plain blobs, it shows the plain contents.", but let's add some
            // options to be a bit more paranoid.
            "--no-color",
            "--no-expand-tabs",
            "--no-notes",
            "--no-textconv",
            String.format("%s:./%s", upstreamSha, path.relativePath()))
        .stdout(outputStream)
        .build()
        .run();
    return outputStream.toString();
  }

  private static boolean isGitRepository(WorkspaceRoot workspaceRoot) {
    // TODO: What if the git repo root is a parent directory of the workspace root?
    // Just call 'git rev-parse --is-inside-work-tree' or similar instead?
    File gitDir = new File(workspaceRoot.directory(), ".git");
    return FileAttributeProvider.getInstance().isDirectory(gitDir);
  }

  /**
   * If we're not on a git branch which tracks a remote, we have no way of determining a WorkingSet.
   */
  private static boolean tracksRemote(WorkspaceRoot workspaceRoot) {
    return getUpstreamSha(workspaceRoot, true) != null;
  }

  /**
   * Returns the git commit SHA corresponding to the most recent commit in the current branch which
   * matches a commit in the currently-tracked remote branch.
   */
  @Nullable
  public static String getUpstreamSha(WorkspaceRoot workspaceRoot, boolean suppressErrors) {
    ByteArrayOutputStream stdout = new ByteArrayOutputStream();
    ByteArrayOutputStream stderr = new ByteArrayOutputStream();

    int retVal =
        ExternalTask.builder(workspaceRoot)
            .args("git", "rev-parse", "@{u}")
            .stdout(stdout)
            .stderr(stderr)
            .build()
            .run();
    if (retVal != 0) {
      if (!suppressErrors) {
        logger.error(stderr);
      }
      return null;
    }
    return StringUtil.trimEnd(stdout.toString(), "\n");
  }
}
