/*
 * 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.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.idea.blaze.base.async.process.ExternalTask;
import com.google.idea.blaze.base.async.process.LineProcessingOutputStream;
import com.google.idea.blaze.base.model.primitives.WorkspacePath;
import com.google.idea.blaze.base.model.primitives.WorkspaceRoot;
import com.google.idea.blaze.base.sync.workspace.WorkingSet;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.text.StringUtil;

import javax.annotation.Nullable;
import java.io.ByteArrayOutputStream;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Vcs diff provider for git.
 */
public class GitDiffProvider {

  private static final Logger LOG = Logger.getInstance(GitDiffProvider.class);

  /**
   * Finds all changes between HEAD and the git commit specified by
   * the provided SHA.<br>
   * Returns null if an error occurred.
   */
  @Nullable
  public static WorkingSet calculateDiff(
    WorkspaceRoot workspaceRoot,
    String upstreamSha) {

    String gitRoot = getConsoleOutput(workspaceRoot, "git", "rev-parse", "--show-toplevel");
    if (gitRoot == null) {
      return null;
    }
    GitStatusLineProcessor processor = new GitStatusLineProcessor(workspaceRoot, gitRoot);
    ByteArrayOutputStream stderr = new ByteArrayOutputStream();

    // Do a git diff to find all modified files we know about
    int retVal = ExternalTask.builder(workspaceRoot, ImmutableList.of("git", "diff", "--name-status", "--no-renames", upstreamSha))
      .stdout(LineProcessingOutputStream.of(processor))
      .stderr(stderr)
      .build()
      .run();
    if (retVal != 0) {
      LOG.error(stderr);
      return null;
    }

    // Finally list all untracked files, as they're not caught by the git diff step above
    String untrackedFilesOutput = getConsoleOutput(workspaceRoot, "git", "ls-files", "--others", "--exclude-standard");
    if (untrackedFilesOutput == null) {
      return null;
    }

    List<WorkspacePath> untrackedFiles = Arrays.asList(untrackedFilesOutput.split("\n"))
      .stream()
      .filter(s -> !Strings.isNullOrEmpty(s))
      .filter(WorkspacePath::validate)
      .map(WorkspacePath::new)
      .collect(Collectors.toList());

    return new WorkingSet(
      ImmutableList.<WorkspacePath>builder().addAll(processor.addedFiles).addAll(untrackedFiles).build(),
      ImmutableList.copyOf(processor.modifiedFiles),
      ImmutableList.copyOf(processor.deletedFiles)
    );
  }

  /**
   * @return the console output, in string form, or null if there was a non-zero exit code.
   */
  @Nullable
  private static String getConsoleOutput(WorkspaceRoot workspaceRoot, String... commands) {
    ByteArrayOutputStream stdout = new ByteArrayOutputStream();
    ByteArrayOutputStream stderr = new ByteArrayOutputStream();

    int retVal = ExternalTask.builder(workspaceRoot, ImmutableList.copyOf(commands))
      .stdout(stdout)
      .stderr(stderr)
      .build()
      .run();
    if (retVal != 0) {
      LOG.error(stderr);
      return null;
    }
    return StringUtil.trimEnd(stdout.toString(), "\n");
  }

}
