// Copyright (C) 2015 Advanced Micro Devices, Inc.  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.amd.gerrit.plugins.manifestsubscription;

import com.amd.gerrit.plugins.manifestsubscription.manifest.Manifest;
import com.google.common.collect.*;
import com.google.gerrit.common.ChangeHooks;
import com.google.gerrit.extensions.annotations.PluginName;
import com.google.gerrit.extensions.events.GitReferenceUpdatedListener;
import com.google.gerrit.extensions.events.LifecycleListener;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.MetaDataUpdate;
import com.google.gerrit.server.git.ProjectConfig;
import com.google.gerrit.server.project.ProjectCache;
import com.google.inject.Inject;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.xml.bind.JAXBException;
import java.io.IOException;
import java.util.*;

public class ManifestSubscription implements
    GitReferenceUpdatedListener, LifecycleListener {
  private static final Logger log =
      LoggerFactory.getLogger(ManifestSubscription.class);

  private static final String KEY_BRANCH = "branch";
  private static final String KEY_STORE = "store";

  static final String STORE_BRANCH_PREFIX = "refs/heads/m/";

  private final String pluginName;

  private final MetaDataUpdate.Server metaDataUpdateFactory;
  private final GitRepositoryManager gitRepoManager;
  private final ProjectCache projectCache;
  private final ChangeHooks changeHooks;


  /**
   * source project lookup
   * manifest source project name, plugin config
   **/
  private Map<String, PluginProjectConfig> enabledManifestSource = Maps.newHashMap();

  /**
   * manifest store lookup
   * repo name, branch (branchPath), Manifest
   */
  private Table<String, String, Manifest> manifestStores = HashBasedTable.create();

  /**
   * manifest source lookup
   * repo name, branch (branchPath), manifest source repo
   */
  private Table<String, String, String> manifestSource = HashBasedTable.create();

  /**
   * lookup
   * subscribed project name and branch, manifest dest store, <manifest dest branch Project>
   **/
  private Table<ProjectBranchKey, String, Map<String, Set<
      com.amd.gerrit.plugins.manifestsubscription.manifest.Project>>> subscribedRepos = HashBasedTable.create();

  public Set<String> getEnabledManifestSource() {
    return ImmutableSet.copyOf(enabledManifestSource.keySet());
  }

  public Set<ProjectBranchKey> getSubscribedProjects() {
    return ImmutableSet.copyOf(subscribedRepos.rowKeySet());
  }

  @Override
  public void start() {
    ProjectConfig config;
    for (Project.NameKey p : projectCache.all()) {
      //TODO parallelize parsing/load up?
      try {
        config = ProjectConfig.read(metaDataUpdateFactory.create(p));
        loadStoreFromProjectConfig(p.toString(), config);

      } catch (IOException | ConfigInvalidException | JAXBException e) {
        log.error(e.toString());
        e.printStackTrace();
      }
    }
  }

  @Override
  public void stop() {

  }

  @Inject
  ManifestSubscription(MetaDataUpdate.Server metaDataUpdateFactory,
                       GitRepositoryManager gitRepoManager,
                       @PluginName String pluginName,
                       ProjectCache projectCache,
                       ChangeHooks changeHooks) {
    this.metaDataUpdateFactory = metaDataUpdateFactory;
    this.gitRepoManager = gitRepoManager;
    this.pluginName = pluginName;
    this.projectCache = projectCache;
    this.changeHooks = changeHooks;
  }

  @Override
  public void onGitReferenceUpdated(Event event) {
    String projectName = event.getProjectName();
    String refName = event.getRefName();
    String branchName = refName.startsWith("refs/heads/") ?
        refName.substring(11) : "";
    ProjectBranchKey pbKey = new ProjectBranchKey(projectName, branchName);

    if ("refs/meta/config".equals(refName)) {
      // possible change in enabled repos
      processProjectConfigChange(event);
    } else if (enabledManifestSource.containsKey(projectName) &&
        enabledManifestSource.get(projectName)
            .getBranches().contains(branchName)) {
      processManifestChange(event, projectName, branchName);

    } else if (subscribedRepos.containsRow(pbKey)) {
      //updates in subscribed repos

      // Manifest store and branch
      Map<String, Map<String, Set<
          com.amd.gerrit.plugins.manifestsubscription.manifest.Project>>>
          destinations = subscribedRepos.row(pbKey);

      for (String store : destinations.keySet()) {
        for (String storeBranch : destinations.get(store).keySet()) {
          Set<com.amd.gerrit.plugins.manifestsubscription.manifest.Project> ps
              = destinations.get(store).get(storeBranch);

          Manifest manifest = manifestStores.get(store, storeBranch);
          String manifestSrc = manifestSource.get(store, storeBranch);
          StringBuilder extraCommitMsg = new StringBuilder();

          Project.NameKey p = new Project.NameKey(projectName);
          try (Repository r = gitRepoManager.openRepository(p);
               RevWalk walk = new RevWalk(r)) {

            RevCommit c = walk.parseCommit(
                ObjectId.fromString(event.getNewObjectId()));

            extraCommitMsg.append(event.getNewObjectId().substring(0,7));
            extraCommitMsg.append(" ");
            extraCommitMsg.append(projectName);
            extraCommitMsg.append(" ");
            extraCommitMsg.append(c.getShortMessage());
          } catch (IOException e) {
            e.printStackTrace();
          }

          // these are project from the above manifest previously
          // cached in the lookup table
          for (com.amd.gerrit.plugins.manifestsubscription.manifest.Project
              updateProject : ps) {
            updateProject.setRevision(event.getNewObjectId());
          }

          try {
            Utilities.updateManifest(gitRepoManager, metaDataUpdateFactory,
                changeHooks, store, STORE_BRANCH_PREFIX + storeBranch,
                manifest, manifestSrc, extraCommitMsg.toString(), null);
          } catch (JAXBException | IOException e) {
            e.printStackTrace();
          }

        }
      }

    }


  }

  private void updateProjectRev(String projectName, String branch, String rev,
                                List<com.amd.gerrit.plugins.
                                    manifestsubscription.manifest.Project> projects) {
    //TODO optimize to not have to iterate through manifest?
    for (com.amd.gerrit.plugins.manifestsubscription.manifest.Project project : projects) {
      if (Objects.equals(projectName, project.getName()) &&
          Objects.equals(branch, project.getUpstream())) {
        project.setRevision(rev);
      }

      if (project.getProject().size() > 0) {
        updateProjectRev(projectName, branch, rev, project.getProject());
      }
    }

  }

  private void processManifestChange(Event event,
                                     String projectName, String branchName) {
    try {
      VersionedManifests versionedManifests = parseManifests(event);
      processManifestChange(versionedManifests, projectName, branchName);
    } catch (JAXBException | IOException | ConfigInvalidException e) {
      e.printStackTrace();
    }

  }

  private void processManifestChange(VersionedManifests versionedManifests,
                                     String projectName, String branchName) {
    //possible manifest update in subscribing repos
    //TODO Fix, right now update all manifest every time
    //TODO even when only one of the manifest has changed

    try {
      if (versionedManifests != null) {
        CanonicalManifest cManifest = new CanonicalManifest(versionedManifests);
        Set<String> manifests = versionedManifests.getManifestPaths();
        Manifest manifest;
        String store = enabledManifestSource.get(projectName).getStore();
        Table<String, String, String> lookup = HashBasedTable.create();

        // Remove old manifest from subscription if destination store and branch
        // matches manifest source being updated
        // TODO again, this assume 1-1 map between store and manifest store
        Map<String,
            Set<com.amd.gerrit.plugins.manifestsubscription.manifest.Project>> branchPaths;
        for (Table.Cell<ProjectBranchKey, String,
            Map<String,
                Set<com.amd.gerrit.plugins.manifestsubscription.manifest.Project>>> cell :
            subscribedRepos.cellSet()) {
          if (store.equals(cell.getColumnKey())) {
            branchPaths = cell.getValue();

            Iterator<String> iter = branchPaths.keySet().iterator();
            String branchPath;
            while (iter.hasNext()) {
              branchPath = iter.next();
              if (branchPath.startsWith(branchName)) {
                iter.remove();
                manifestStores.remove(store, branchPath);
                manifestSource.remove(store, branchPath);
              }
            }
          }
        }

        //TODO need to make sure remote is pointing to this server?
        //TODO this may be impossible
        //TODO only monitor projects without 'remote' attribute / only using default?

        for (String path : manifests) {
          String bp = branchName + "/" + path;
          try {
            manifest = cManifest.getCanonicalManifest(path);

            VersionedManifests.affixManifest(gitRepoManager, manifest, lookup);

            watchCanonicalManifest(manifest, store, bp, projectName);
            //save manifest
            //TODO added the m/ to the ref to to work around LOCK_FAILURE error of creating master/bla/bla
            //TODO (because default master ref already exists) better solution?
            updateManifest(store, STORE_BRANCH_PREFIX + bp,
                           manifest, projectName);

          } catch (ManifestReadException | GitAPIException e) {
            e.printStackTrace();
          }

        }

      }
    } catch (JAXBException | IOException e) {
      e.printStackTrace();
    }

  }

  private void watchCanonicalManifest(Manifest manifest, String store,
                                      String branchPath, String manifestSrc) {
    String defaultBranch;
    if (manifest.getDefault() != null &&
        manifest.getDefault().getRevision() != null) {
      defaultBranch = manifest.getDefault().getRevision();
    } else {
      defaultBranch = "";
    }

    manifestStores.put(store, branchPath, manifest);
    manifestSource.put(store, branchPath, manifestSrc);

    List<com.amd.gerrit.plugins.manifestsubscription.manifest.Project> projects
        = manifest.getProject();
    watchProjectsInCanonicalManifest(store, branchPath, defaultBranch, projects);
  }

  private void watchProjectsInCanonicalManifest(String store, String branchPath,
                                                String defaultBranch,
                                                List<com.amd.gerrit.plugins.manifestsubscription.manifest.Project> projects) {
    ProjectBranchKey pbKey;
    for (com.amd.gerrit.plugins.manifestsubscription.manifest.Project project : projects) {
      if (manifestStores.containsRow(project.getName()) &&
          !manifestStores.row(project.getName()).isEmpty()) {
        // Skip if it's one of the repo for storing
        // manifest to avoid infinite loop
        // This is a bit too general, but it's done to avoid the complexity
        // of actually tracing out the loop
        // i.e. manifest1->store2 --> manifest2->store1
        continue;
      }

      // Make sure revision is branch ref w/o refs/heads
      String branch = project.getRevision() == null ?
          defaultBranch : (project.getUpstream() != null ?
          project.getUpstream() : project.getRevision());
      pbKey = new ProjectBranchKey(project.getName(),
          Repository.shortenRefName(branch));


      //TODO only update manifests that changed
      if (!subscribedRepos.contains(pbKey, store)) {
        subscribedRepos.put(pbKey, store,
            Maps.<String, Set<com.amd.gerrit.plugins.manifestsubscription.manifest.Project>>newHashMap());
      }

      Map<String,
          Set<com.amd.gerrit.plugins.manifestsubscription.manifest.Project>> ps;
      ps = subscribedRepos.get(pbKey, store);
      if (!ps.containsKey(branchPath)) {
        ps.put(branchPath,
            Sets.<com.amd.gerrit.plugins.manifestsubscription.manifest.Project>newHashSet());
      }
      ps.get(branchPath).add(project);

      if (project.getProject().size() > 0) {
        watchProjectsInCanonicalManifest(store, branchPath, defaultBranch,
            project.getProject());
      }
    }
  }

  private void processProjectConfigChange(Event event) {
    Project.NameKey p = new Project.NameKey(event.getProjectName());

    //TODO test two separate project configured to the same store
    try {
      ProjectConfig oldCfg = parseConfig(p, event.getOldObjectId());
      ProjectConfig newCfg = parseConfig(p, event.getNewObjectId());

      //TODO selectively update changes instead of complete reset
      if (oldCfg != null) {
        String oldStore =
            oldCfg.getPluginConfig(pluginName).getString(KEY_STORE);

        if (oldStore != null && !oldStore.isEmpty()) {
          //TODO FIX assume unique store for each manifest source (1-1 map)
          manifestStores.row(oldStore).clear();
          manifestSource.row(oldStore).clear();
          enabledManifestSource.remove(event.getProjectName());

          Iterator<Table.Cell<ProjectBranchKey, String, Map<String,
              Set<com.amd.gerrit.plugins.manifestsubscription.manifest.Project>>>> iter =
              subscribedRepos.cellSet().iterator();
          while (iter.hasNext()) {
            if (oldStore.equals(iter.next().getColumnKey())) {
              iter.remove();
            }
          }
        }
      }

      if (newCfg != null) {
        loadStoreFromProjectConfig(event.getProjectName(), newCfg);

      }
    } catch (IOException | ConfigInvalidException | JAXBException e) {
      e.printStackTrace();
    }
  }

  private void loadStoreFromProjectConfig(String projectName,
                                          ProjectConfig config)
      throws JAXBException, IOException, ConfigInvalidException {
    String newStore =
        config.getPluginConfig(pluginName).getString(KEY_STORE);

    if (newStore != null) {
      newStore = newStore.trim();
      if (!newStore.isEmpty()) {
        Set<String> branches = Sets.newHashSet(
            config.getPluginConfig(pluginName)
                .getStringList(KEY_BRANCH));

        if (branches.size() > 0) {
          PluginProjectConfig ppc = new PluginProjectConfig(newStore, branches);

          enabledManifestSource.put(projectName, ppc);
          Project.NameKey nameKey = new Project.NameKey(projectName);
          VersionedManifests versionedManifests;
          for (String branch : branches) {
            versionedManifests = parseManifests(nameKey, branch);
            processManifestChange(versionedManifests, projectName, branch);
          }
        }
      }
    }
  }

  private ProjectConfig parseConfig(Project.NameKey p, String idStr)
      throws IOException, ConfigInvalidException {
    ObjectId id = ObjectId.fromString(idStr);
    if (ObjectId.zeroId().equals(id)) {
      return null;
    }
    return ProjectConfig.read(metaDataUpdateFactory.create(p), id);
  }

  private VersionedManifests parseManifests(Event event)
      throws JAXBException, IOException, ConfigInvalidException {
    Project.NameKey p = new Project.NameKey(event.getProjectName());
    return parseManifests(p, event.getRefName());
  }

  private VersionedManifests parseManifests(Project.NameKey p, String refName)
      throws IOException, JAXBException, ConfigInvalidException {

    Repository repo = gitRepoManager.openRepository(p);
    ObjectId commitId = repo.resolve(refName);
    MetaDataUpdate update = metaDataUpdateFactory.create(p);
    VersionedManifests vManifests = new VersionedManifests(refName);
    vManifests.load(update, commitId);

    return vManifests;
  }

  private void updateManifest(String projectName, String refName,
                              Manifest manifest, String manifestSrc)
      throws JAXBException, IOException {
    Utilities.updateManifest(gitRepoManager, metaDataUpdateFactory, changeHooks,
        projectName, refName, manifest, manifestSrc, "", null);
  }

}
