/*
 * Copyright (c) 2013 VMware, Inc. All Rights Reserved.
 */
package com.vmware.gerrit.owners.common;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimaps;
import com.google.common.collect.SetMultimap;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.Patch;
import com.google.gerrit.server.account.AccountResolver;
import com.google.gerrit.server.patch.PatchList;
import com.google.gerrit.server.patch.PatchListEntry;
import com.google.gwtorm.server.OrmException;
import org.eclipse.jgit.lib.Repository;
import org.gitective.core.BlobUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * Calculates the owners of a patch list.
 */
// TODO(vspivak): provide assisted factory
public class PathOwners {

  private static final Logger log = LoggerFactory.getLogger(PathOwners.class);

  private final SetMultimap<String, Account.Id> owners;

  private final AccountResolver resolver;

  private final Repository repository;

  private final PatchList patchList;

  public PathOwners(AccountResolver resolver, Repository repository, PatchList patchList) throws OrmException {
    this.repository = repository;
    this.resolver = resolver;
    this.patchList = patchList;

    owners = Multimaps.unmodifiableSetMultimap(fetchOwners());
  }

  /**
   * Returns a read only view of the paths to owners mapping.
   *
   * @return multimap of paths to owners
   */
  public SetMultimap<String, Account.Id> get() {
    return owners;
  }

  /**
   * Fetched the owners for the associated patch list.
   *
   * @return multimap of paths to owners
   */
  private SetMultimap<String, Account.Id> fetchOwners() throws OrmException {
    SetMultimap<String, Account.Id> result = HashMultimap.create();
    Map<String, PathOwnersEntry> entries = new HashMap<String, PathOwnersEntry>();

    PathOwnersEntry rootEntry = new PathOwnersEntry();
    OwnersConfig rootConfig = getOwners("OWNERS");
    if (rootConfig != null) {
      rootEntry.setOwnersPath("OWNERS");
      rootEntry.addOwners(getOwnersFromEmails(rootConfig.getOwners()));
    }

    Set<String> paths = getModifiedPaths();
    for (String path : paths) {
      String[] parts = path.split("/");

      PathOwnersEntry currentEntry = rootEntry;
      StringBuilder builder = new StringBuilder();

      // Iterate through the parent paths, not including the file name itself
      for (int i = 0, partsLength = parts.length - 1; i < partsLength; i++) {
        String part = parts[i];
        builder.append(part).append("/");
        String partial = builder.toString();

        // Skip if we already parsed this path
        if (!entries.containsKey(partial)) {
          String ownersPath = partial + "OWNERS";
          OwnersConfig config = getOwners(ownersPath);
          if (config != null) {
            PathOwnersEntry entry = new PathOwnersEntry();
            entry.setOwnersPath(ownersPath);
            entry.addOwners(getOwnersFromEmails(config.getOwners()));

            if (config.isInherited()) {
              entry.addOwners(currentEntry.getOwners());
            }

            currentEntry = entry;
          }

          entries.put(partial, currentEntry);
        } else {
          currentEntry = entries.get(partial);
        }
      }

      result.putAll(path, currentEntry.getOwners());
    }

    return result;
  }

  /**
   * Parses the patch list for any paths that were modified.
   *
   * @return set of modified paths.
   */
  private Set<String> getModifiedPaths() {
    Set<String> paths = new HashSet<String>();
    for (PatchListEntry patch : patchList.getPatches()) {
      // Ignore commit message
      if (!patch.getNewName().equals("/COMMIT_MSG")) {
        paths.add(patch.getNewName());

        // If a file was moved then we need approvals for old and new path
        if (patch.getChangeType() == Patch.ChangeType.RENAMED) {
          paths.add(patch.getOldName());
        }
      }
    }
    return paths;
  }

  /**
   * Returns the parsed OwnersConfig file for the given path if it exists.
   *
   * @param ownersPath path to OWNERS file in the git repo
   * @return config or null if it doesn't exist
   */
  private OwnersConfig getOwners(String ownersPath) {
    String owners = BlobUtils.getContent(repository, "master", ownersPath);

    if (owners != null) {
      ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
      try {
        return mapper.readValue(owners, OwnersConfig.class);
      } catch (IOException e) {
        log.warn("Invalid OWNERS file: {}", ownersPath, e);
        return null;
      }
    }

    return null;
  }

  /**
   * Translates emails to Account.Ids.
   * @param emails emails to translate
   * @return set of account ids
   */
  private Set<Account.Id> getOwnersFromEmails(Set<String> emails) throws OrmException {
    Set<Account.Id> result = new HashSet<Account.Id>();
    for (String email : emails) {
      Set<Account.Id> ids = resolver.findAll(email);
      result.addAll(ids);
    }
    return result;
  }
}
