// Copyright (C) 2017 The Android Open Source Project
//
// 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.googlesource.gerrit.plugins.findowners;

import static com.google.common.base.Strings.isNullOrEmpty;
import static com.googlesource.gerrit.plugins.findowners.Config.REJECT_ERROR_IN_OWNERS;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Multimap;
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.extensions.annotations.Exports;
import com.google.gerrit.extensions.api.projects.ProjectConfigEntryType;
import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.account.AccountCache;
import com.google.gerrit.server.account.Emails;
import com.google.gerrit.server.config.PluginConfig;
import com.google.gerrit.server.config.PluginConfigFactory;
import com.google.gerrit.server.config.ProjectConfigEntry;
import com.google.gerrit.server.events.CommitReceivedEvent;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.validators.CommitValidationException;
import com.google.gerrit.server.git.validators.CommitValidationListener;
import com.google.gerrit.server.git.validators.CommitValidationMessage;
import com.google.gerrit.server.patch.PatchListCache;
import com.google.inject.AbstractModule;
import com.google.inject.Inject;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import org.eclipse.jgit.diff.RawText;
import org.eclipse.jgit.lib.FileMode;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectLoader;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.treewalk.TreeWalk;
import org.eclipse.jgit.treewalk.filter.TreeFilter;

/** Check syntax of changed OWNERS files. */
public class OwnersValidator implements CommitValidationListener {
  private static final FluentLogger logger = FluentLogger.forEnclosingClass();

  private interface TreeWalkVisitor {
    void onVisit(TreeWalk tw);
  }

  public static AbstractModule module() {
    return new AbstractModule() {
      @Override
      protected void configure() {
        DynamicSet.bind(binder(), CommitValidationListener.class).to(OwnersValidator.class);
        bind(ProjectConfigEntry.class)
            .annotatedWith(Exports.named(REJECT_ERROR_IN_OWNERS))
            .toInstance(
                new ProjectConfigEntry(
                    "Reject OWNERS Files With Errors",
                    null,
                    ProjectConfigEntryType.BOOLEAN,
                    null,
                    false,
                    "Pushes of commits with errors in OWNERS files will be rejected."));
      }
    };
  }

  private final Config config;
  private final GitRepositoryManager repoManager;
  private final Emails emails;

  @Inject
  OwnersValidator(
      PluginConfigFactory cfgFactory,
      AccountCache accountCache,
      PatchListCache patchListCache,
      GitRepositoryManager repoManager,
      Emails emails) {
    this(cfgFactory, null, accountCache, patchListCache, repoManager, emails);
  }

  @VisibleForTesting
  OwnersValidator(
      PluginConfig config,
      AccountCache accountCache,
      PatchListCache patchListCache,
      GitRepositoryManager repoManager,
      Emails emails) {
    this(null, config, accountCache, patchListCache, repoManager, emails);
  }

  private OwnersValidator(
      PluginConfigFactory cfgFactory,
      PluginConfig config,
      AccountCache accountCache,
      PatchListCache patchListCache,
      GitRepositoryManager repoManager,
      Emails emails) {
    this.config = new Config(cfgFactory, config, accountCache, patchListCache, emails);
    this.repoManager = repoManager;
    this.emails = emails;
  }

  @VisibleForTesting
  String getOwnersFileName() {
    return config.getOwnersFileName();
  }

  @VisibleForTesting
  public String getOwnersFileName(Project project) {
    return config.getOwnersFileName(project);
  }

  @VisibleForTesting
  boolean isActive(Project project) {
    return config.getRejectErrorInOwners(project);
  }

  @VisibleForTesting
  boolean isActive() {
    return config.getRejectErrorInOwners();
  }

  @Override
  public List<CommitValidationMessage> onCommitReceived(CommitReceivedEvent event)
      throws CommitValidationException {
    if (!isActive(event.project)) {
      return new ArrayList<>();
    }
    Checker checker = new Checker(event, false);
    try {
      checker.check(getOwnersFileName(event.project));
      if (checker.hasError()) {
        checker.addError(
            "See OWNERS file syntax document at "
                + "https://gerrit.googlesource.com/plugins/find-owners/+/"
                + "master/src/main/resources/Documentation/syntax.md");
        throw new CommitValidationException("found invalid owners file", checker.messages);
      }
      return checker.messages;
    } catch (IOException e) {
      logger.atSevere().withCause(e).log("Failed in onCommitReceived");
      return new ArrayList<>();
    }
  }

  class Checker {
    // An inner class to keep needed data specific to one commit event.
    CommitReceivedEvent event;
    boolean verbose;
    List<CommitValidationMessage> messages;
    Map<String, ObjectId> allFiles; // changedFilePath => ObjectId
    Map<String, String> readFiles; // project:file => content
    Set<String> checkedFiles; // project:file
    // Collect all email addresses from all files and check each address only once.
    Map<String, Set<String>> email2lines;

    Checker(CommitReceivedEvent event, boolean verbose) {
      this.event = event;
      this.verbose = verbose;
      messages = new ArrayList<>();
      readFiles = new HashMap<>();
      checkedFiles = new HashSet<>();
      email2lines = new HashMap<>();
      try {
        allFiles = getChangedFiles(event.commit, event.revWalk);
      } catch (Exception e) {
        allFiles = new HashMap<>();
        addError("getChangedFiles failed.");
      }
    }

    @VisibleForTesting
    void check(String ownersFileName) throws IOException {
      Map<String, ObjectId> ownerFiles =
          allFiles.entrySet().stream()
              .filter(e -> ownersFileName.equals(new File(e.getKey()).getName()))
              .collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue()));
      String projectName = event.project.getName();
      for (String path : ownerFiles.keySet()) {
        String key = projectName + ":" + path;
        ObjectLoader ol = event.revWalk.getObjectReader().open(ownerFiles.get(path));
        try (InputStream in = ol.openStream()) {
          if (RawText.isBinary(in)) {
            addError(path + " is a binary file"); // OWNERS files cannot be binary
            continue;
          }
        }
        checkedFiles.add(key);
        checkFile(projectName, path, ol);
      }
      checkEmails(emails);
    }

    void checkEmails(Emails emails) {
      List<String> owners = new ArrayList<>(email2lines.keySet());
      if (owners.isEmpty()) {
        return;
      }
      if (verbose) {
        for (String owner : owners) {
          addMsg("owner: " + owner);
        }
      }
      if (emails == null) {
        addError("cannot check owner emails with null Emails cache.");
      }
      String[] ownerEmailsAsArray = new String[owners.size()];
      owners.toArray(ownerEmailsAsArray);
      try {
        Multimap<String, Account.Id> email2ids = emails.getAccountsFor(ownerEmailsAsArray);
        for (String owner : ownerEmailsAsArray) {
          boolean wrongEmail = (email2ids == null);
          if (!wrongEmail) {
            try {
              Collection<Account.Id> ids = email2ids.get(owner);
              wrongEmail = (ids == null || ids.isEmpty());
            } catch (Exception e) {
              wrongEmail = true;
            }
          }
          if (wrongEmail) {
            String locations = String.join(" ", email2lines.get(owner));
            addError("unknown: " + owner + " at " + locations);
          }
        }
      } catch (Exception e) {
        addError("checkEmails failed.");
      }
    }

    void checkFile(String project, String path, String[] lines) {
      addVerboseMsg("checking " + path);
      int num = 0;
      for (String line : lines) {
        checkLine(project, path, ++num, line);
      }
    }

    void checkFile(String project, String path, String content) {
      checkFile(project, path, content.split("\\R"));
    }

    void checkFile(String project, String path, ObjectLoader ol) {
      try {
        BufferedReader reader =
            new BufferedReader(new InputStreamReader(ol.openStream(), StandardCharsets.UTF_8));
        checkFile(project, path, reader.lines().toArray(String[]::new));
      } catch (Exception e) {
        addError("cannot open file: " + path);
      }
    }

    private void collectEmail(String email, String project, String file, int lineNumber) {
      if (!email.equals("*")) {
        email2lines.computeIfAbsent(email, (String k) -> new HashSet<>());
        email2lines.get(email).add(qualifiedPath(project, file) + ":" + lineNumber);
      }
    }

    private boolean hasError() {
      for (CommitValidationMessage m : messages) {
        if (m.isError()) {
          return true;
        }
      }
      return false;
    }

    void addError(String msg) {
      messages.add(new CommitValidationMessage(msg, true));
    }

    String qualifiedPath(String project, String path) {
      return event.project.getName().equals(project) ? path : (project + ":" + path);
    }

    void addSyntaxError(String path, int lineNumber, String line) {
      addError("syntax: " + path + ":" + lineNumber + ": " + line);
    }

    void addMsg(String msg) {
      messages.add(new CommitValidationMessage(msg, false));
    }

    void addVerboseMsg(String msg) {
      if (verbose) {
        addMsg(msg);
      }
    }

    String normalizeChangedFilePath(String dir, String file) {
      try {
        if (file.startsWith("/")) {
          file = new File(file).getCanonicalPath();
        } else {
          file = new File("/" + dir + "/" + file).getCanonicalPath();
        }
      } catch (IOException e) {
        addError("cannot build file path " + dir + ":" + file);
      }
      return file.startsWith("/") ? file.substring(1) : file;
    }

    /**
     * Check if an included file exists and with valid syntax. An included file could be (1) in the
     * current CL, (2) in the same repository, (3) in a different repository, (4) in another CL.
     * Case (4) is not checked yet.
     */
    void checkIncludeOrFile(String project, String path, int num, String line) {
      // project is the including file's project, not necessarily the same as CL event's.
      String directive = Parser.getIncludeOrFile(line);
      String[] KPF = Parser.parseInclude(project, directive);
      if (KPF == null || KPF[1] == null || KPF[2] == null) {
        addSyntaxError(qualifiedPath(project, path), num, line);
      }
      String file = KPF[2];
      String curDir = Util.getParentDir(path);
      String repoFile = normalizeChangedFilePath(curDir, file);
      // Check each file only once.
      String key = KPF[1] + ":" + repoFile;
      if (checkedFiles.contains(key)) {
        addVerboseMsg("skip repeated include of " + key);
        return;
      }
      checkedFiles.add(key);
      if (KPF[1].equals(event.project.getName())) {
        if (allFiles.get(repoFile) != null) {
          // Case (1): included file is in current CL.
          addVerboseMsg("check changed file " + key);
          try {
            ObjectLoader ol = event.revWalk.getObjectReader().open(allFiles.get(repoFile));
            try (InputStream in = ol.openStream()) {
              if (RawText.isBinary(in)) {
                addError(path + " is a binary file"); // OWNERS files cannot be binary
                return;
              }
            }
            checkFile(KPF[1], repoFile, ol);
          } catch (Exception e) {
            addError("cannot open changed file: " + path);
          }
          return;
        }
      }
      // Included file is in repository or other CL.
      addVerboseMsg("check repo file " + key);
      String content =
          OwnersDb.getRepoFile(
              null, /* permissionBackend */
              readFiles,
              repoManager,
              null,
              null,
              KPF[1],
              event.refName,
              repoFile,
              new ArrayList<>());
      if (isNullOrEmpty(content)) { // file not found or not readable.
        addVerboseMsg("cannot find file: " + key);
        // unchecked: including-file-path : line number : source line
        addMsg("unchecked: " + qualifiedPath(project, path) + ":" + num + ": " + directive);
      } else {
        checkFile(KPF[1], repoFile, content);
      }
    }

    void checkLine(String project, String path, int lineNumber, String line) {
      String email;
      String[] owners;
      if (Parser.isComment(line) || Parser.isNoParent(line)) {
        // no email address to check
      } else if ((email = Parser.parseEmail(line)) != null) {
        collectEmail(email, project, path, lineNumber);
      } else if ((owners = Parser.parsePerFileOwners(line)) != null) {
        for (String owner : owners) {
          if (owner.startsWith("file:")) {
            // Pass the whole line, not just owner, to report any syntax error.,
            checkIncludeOrFile(project, path, lineNumber, line);
          } else if (!owner.equals(Parser.TOK_SET_NOPARENT)) {
            collectEmail(owner, project, path, lineNumber);
          }
        }
      } else if (Parser.isInclude(line)) {
        checkIncludeOrFile(project, path, lineNumber, line);
      } else {
        addSyntaxError(qualifiedPath(project, path), lineNumber, line);
      }
    }
  } // end of inner class Checker

  /** Return a map from "Path to changed file" to "ObjectId of the file". */
  private static Map<String, ObjectId> getChangedFiles(RevCommit c, RevWalk revWalk)
      throws IOException {
    final Map<String, ObjectId> content = new HashMap<>();
    visitChangedEntries(
        c,
        revWalk,
        new TreeWalkVisitor() {
          @Override
          public void onVisit(TreeWalk tw) {
            // getPathString() returns path names without leading "/"
            if (isFile(tw)) {
              content.put(tw.getPathString(), tw.getObjectId(0));
            }
          }
        });
    return content;
  }

  private static boolean isFile(TreeWalk tw) {
    return FileMode.EXECUTABLE_FILE.equals(tw.getRawMode(0))
        || FileMode.REGULAR_FILE.equals(tw.getRawMode(0));
  }

  /**
   * Find all TreeWalk entries which differ between the commit and its parents. If a TreeWalk entry
   * is found this method calls the onVisit() method of the class TreeWalkVisitor.
   */
  private static void visitChangedEntries(RevCommit c, RevWalk revWalk, TreeWalkVisitor visitor)
      throws IOException {
    try (TreeWalk tw = new TreeWalk(revWalk.getObjectReader())) {
      tw.setRecursive(true);
      tw.setFilter(TreeFilter.ANY_DIFF);
      tw.addTree(c.getTree());
      if (c.getParentCount() > 0) {
        for (RevCommit p : c.getParents()) {
          if (p.getTree() == null) {
            revWalk.parseHeaders(p);
          }
          tw.addTree(p.getTree());
        }
        while (tw.next()) {
          if (isDifferentToAllParents(c, tw)) {
            visitor.onVisit(tw);
          }
        }
      } else {
        while (tw.next()) {
          visitor.onVisit(tw);
        }
      }
    }
  }

  private static boolean isDifferentToAllParents(RevCommit c, TreeWalk tw) {
    if (c.getParentCount() > 1) {
      for (int p = 1; p <= c.getParentCount(); p++) {
        if (tw.getObjectId(0).equals(tw.getObjectId(p))) {
          return false;
        }
      }
    }
    return true;
  }
}
