// Copyright (C) 2018 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.google.gerrit.acceptance.testsuite.project;

import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.gerrit.entities.RefNames.REFS_CONFIG;
import static com.google.gerrit.server.project.ProjectConfig.PROJECT_CONFIG;
import static com.google.gerrit.testing.TestActionRefUpdateContext.openTestRefUpdateContext;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Objects.requireNonNull;

import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.TestCapability;
import com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.TestLabelPermission;
import com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.TestPermission;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.entities.AccessSection;
import com.google.gerrit.entities.AccountGroup;
import com.google.gerrit.entities.GroupReference;
import com.google.gerrit.entities.Permission;
import com.google.gerrit.entities.PermissionRule;
import com.google.gerrit.entities.Project;
import com.google.gerrit.entities.RefNames;
import com.google.gerrit.server.config.AllProjectsName;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.meta.MetaDataUpdate;
import com.google.gerrit.server.project.CreateProjectArgs;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectConfig;
import com.google.gerrit.server.project.ProjectCreator;
import com.google.gerrit.server.update.context.RefUpdateContext;
import com.google.inject.Inject;
import java.io.IOException;
import java.util.ArrayList;
import org.apache.commons.lang3.RandomStringUtils;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.ObjectLoader;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevTree;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.treewalk.TreeWalk;

public class ProjectOperationsImpl implements ProjectOperations {
  private final AllProjectsName allProjectsName;
  private final GitRepositoryManager repoManager;
  private final MetaDataUpdate.Server metaDataUpdateFactory;
  private final ProjectCache projectCache;
  private final ProjectConfig.Factory projectConfigFactory;
  private final ProjectCreator projectCreator;

  @Inject
  ProjectOperationsImpl(
      AllProjectsName allProjectsName,
      GitRepositoryManager repoManager,
      MetaDataUpdate.Server metaDataUpdateFactory,
      ProjectCache projectCache,
      ProjectConfig.Factory projectConfigFactory,
      ProjectCreator projectCreator) {
    this.allProjectsName = allProjectsName;
    this.repoManager = repoManager;
    this.metaDataUpdateFactory = metaDataUpdateFactory;
    this.projectCache = projectCache;
    this.projectConfigFactory = projectConfigFactory;
    this.projectCreator = projectCreator;
  }

  @Override
  public TestProjectCreation.Builder newProject() {
    return TestProjectCreation.builder(this::createNewProject);
  }

  private Project.NameKey createNewProject(TestProjectCreation projectCreation) throws Exception {
    String name = projectCreation.name().orElseGet(() -> RandomStringUtils.randomAlphabetic(8));

    CreateProjectArgs args = new CreateProjectArgs();
    args.setProjectName(name);
    args.permissionsOnly = projectCreation.permissionOnly().orElse(false);
    args.branch =
        projectCreation.branches().stream().map(RefNames::fullName).collect(toImmutableList());
    args.createEmptyCommit = projectCreation.createEmptyCommit().orElse(true);
    projectCreation.parent().ifPresent(p -> args.newParent = p);
    // ProjectCreator wants non-null owner IDs.
    args.ownerIds = new ArrayList<>(projectCreation.owners());
    projectCreation.submitType().ifPresent(st -> args.submitType = st);
    projectCreator.createProject(args);
    return Project.nameKey(name);
  }

  @Override
  public ProjectOperations.PerProjectOperations project(Project.NameKey key) {
    return new PerProjectOperations(key);
  }

  @Override
  public TestProjectUpdate.Builder allProjectsForUpdate() {
    return project(allProjectsName).forUpdate();
  }

  private class PerProjectOperations implements ProjectOperations.PerProjectOperations {
    Project.NameKey nameKey;

    PerProjectOperations(Project.NameKey nameKey) {
      this.nameKey = nameKey;
    }

    @Override
    public RevCommit getHead(String branch) {
      return requireNonNull(headOrNull(branch));
    }

    @Override
    public boolean hasHead(String branch) {
      return headOrNull(branch) != null;
    }

    @Override
    public TestProjectUpdate.Builder forUpdate() {
      return TestProjectUpdate.builder(nameKey, allProjectsName, this::updateProject);
    }

    private void updateProject(TestProjectUpdate projectUpdate)
        throws IOException, ConfigInvalidException {
      try (RefUpdateContext ctx = openTestRefUpdateContext()) {
        try (MetaDataUpdate metaDataUpdate = metaDataUpdateFactory.create(nameKey)) {
          ProjectConfig projectConfig = projectConfigFactory.read(metaDataUpdate);
          if (projectUpdate.removeAllAccessSections()) {
            projectConfig.getAccessSections().forEach(as -> projectConfig.remove(as));
          }
          removePermissions(projectConfig, projectUpdate.removedPermissions());
          addCapabilities(projectConfig, projectUpdate.addedCapabilities());
          addPermissions(projectConfig, projectUpdate.addedPermissions());
          addLabelPermissions(projectConfig, projectUpdate.addedLabelPermissions());
          setExclusiveGroupPermissions(projectConfig, projectUpdate.exclusiveGroupPermissions());
          projectConfig.updateProject(
              update ->
                  projectUpdate
                      .booleanProjectConfigs()
                      .forEach((name, value) -> update.setBooleanConfig(name, value)));
          projectConfig.commit(metaDataUpdate);
        }
        projectCache.evictAndReindex(nameKey);
      }
    }

    private void removePermissions(
        ProjectConfig projectConfig,
        ImmutableList<TestProjectUpdate.TestPermissionKey> removedPermissions) {
      for (TestProjectUpdate.TestPermissionKey p : removedPermissions) {
        projectConfig.upsertAccessSection(
            p.section(),
            as -> {
              Permission.Builder permission = as.upsertPermission(p.name());
              if (p.group().isPresent()) {
                GroupReference group =
                    GroupReference.create(p.group().get(), p.group().get().get());
                group = projectConfig.resolve(group);
                permission.removeRule(group);
              } else {
                permission.clearRules();
              }
            });
      }
    }

    private void addCapabilities(
        ProjectConfig projectConfig, ImmutableList<TestCapability> addedCapabilities) {
      for (TestCapability c : addedCapabilities) {
        PermissionRule.Builder rule = newRule(projectConfig, c.group());
        rule.setRange(c.min(), c.max());
        projectConfig.upsertAccessSection(
            AccessSection.GLOBAL_CAPABILITIES, as -> as.upsertPermission(c.name()).add(rule));
      }
    }

    private void addPermissions(
        ProjectConfig projectConfig, ImmutableList<TestPermission> addedPermissions) {
      for (TestPermission p : addedPermissions) {
        PermissionRule.Builder rule = newRule(projectConfig, p.group());
        rule.setAction(p.action());
        rule.setForce(p.force());
        projectConfig.upsertAccessSection(p.ref(), as -> as.upsertPermission(p.name()).add(rule));
      }
    }

    private void addLabelPermissions(
        ProjectConfig projectConfig, ImmutableList<TestLabelPermission> addedLabelPermissions) {
      for (TestLabelPermission p : addedLabelPermissions) {
        PermissionRule.Builder rule = newRule(projectConfig, p.group());
        rule.setAction(p.action());
        rule.setRange(p.min(), p.max());
        String permissionName;
        if (p.isAddPermission()) {
          permissionName =
              p.impersonation() ? Permission.forLabelAs(p.name()) : Permission.forLabel(p.name());
        } else {
          permissionName = Permission.forRemoveLabel(p.name());
        }
        projectConfig.upsertAccessSection(
            p.ref(), as -> as.upsertPermission(permissionName).add(rule));
      }
    }

    private void setExclusiveGroupPermissions(
        ProjectConfig projectConfig,
        ImmutableMap<TestProjectUpdate.TestPermissionKey, Boolean> exclusiveGroupPermissions) {
      exclusiveGroupPermissions.forEach(
          (key, exclusive) ->
              projectConfig.upsertAccessSection(
                  key.section(),
                  as -> as.upsertPermission(key.name()).setExclusiveGroup(exclusive)));
    }

    @Nullable
    private RevCommit headOrNull(String branch) {
      branch = RefNames.fullName(branch);

      try (Repository repo = repoManager.openRepository(nameKey);
          RevWalk rw = new RevWalk(repo)) {
        Ref r = repo.exactRef(branch);
        return r == null ? null : rw.parseCommit(r.getObjectId());
      } catch (Exception e) {
        throw new IllegalStateException(e);
      }
    }

    @Override
    public ProjectConfig getProjectConfig() {
      try (Repository repo = repoManager.openRepository(nameKey)) {
        ProjectConfig projectConfig = projectConfigFactory.create(nameKey);
        projectConfig.load(nameKey, repo);
        return projectConfig;
      } catch (Exception e) {
        throw new IllegalStateException(e);
      }
    }

    @Override
    public Config getConfig() {
      try (Repository repo = repoManager.openRepository(nameKey);
          RevWalk rw = new RevWalk(repo)) {
        Ref ref = repo.exactRef(REFS_CONFIG);
        if (ref == null) {
          return new Config();
        }
        RevTree tree = rw.parseTree(ref.getObjectId());
        TreeWalk tw = TreeWalk.forPath(rw.getObjectReader(), PROJECT_CONFIG, tree);
        if (tw == null) {
          return new Config();
        }
        ObjectLoader loader = rw.getObjectReader().open(tw.getObjectId(0));
        String text = new String(loader.getCachedBytes(), UTF_8);
        Config config = new Config();
        config.fromText(text);
        return config;
      } catch (Exception e) {
        throw new IllegalStateException(e);
      }
    }

    private void setConfig(Config projectConfig) {
      try (TestRepository<Repository> repo =
          new TestRepository<>(repoManager.openRepository(nameKey))) {
        repo.update(
            RefNames.REFS_CONFIG,
            repo.commit()
                .message("Update project.config from test")
                .parent(getHead(RefNames.REFS_CONFIG))
                .add(ProjectConfig.PROJECT_CONFIG, projectConfig.toText()));
      } catch (Exception e) {
        throw new IllegalStateException(
            "updating project.config of project " + nameKey + " failed", e);
      }
    }

    @Override
    public TestProjectInvalidation.Builder forInvalidation() {
      return TestProjectInvalidation.builder(this::invalidateProject);
    }

    private void invalidateProject(TestProjectInvalidation testProjectInvalidation)
        throws Exception {
      if (testProjectInvalidation.makeProjectConfigInvalid()) {
        Config projectConfig = new Config();
        projectConfig.fromText(getConfig().toText());

        // Make the project config invalid by adding a permission entry with an invalid permission
        // name.
        projectConfig.setString(
            "access", "refs/*", "Invalid Permission Name", "group Administrators");

        setConfig(projectConfig);
        try {
          projectCache.evictAndReindex(nameKey);
        } catch (Exception e) {
          // Evicting the project from the cache, also triggers a reindex of the project.
          // The reindex step fails if the project config is invalid. That's fine, since it was our
          // intention to make the project config invalid. Hence we ignore exceptions that are cause
          // by an invalid project config here.
          if (!Throwables.getCausalChain(e).stream()
              .anyMatch(ConfigInvalidException.class::isInstance)) {
            throw e;
          }
        }
      }
      if (!testProjectInvalidation.projectConfigUpdater().isEmpty()) {
        Config projectConfig = new Config();
        projectConfig.fromText(getConfig().toText());
        testProjectInvalidation.projectConfigUpdater().forEach(c -> c.accept(projectConfig));
        setConfig(projectConfig);
        try {
          projectCache.evictAndReindex(nameKey);
        } catch (Exception e) {
          // Evicting the project from the cache, also triggers a reindex of the project.
          // The reindex step fails if the project config is invalid. That's fine, since it was our
          // intention to make the project config invalid. Hence we ignore exceptions that are cause
          // by an invalid project config here.
          if (!Throwables.getCausalChain(e).stream()
              .anyMatch(ConfigInvalidException.class::isInstance)) {
            throw e;
          }
        }
      }
    }
  }

  private static PermissionRule.Builder newRule(
      ProjectConfig project, AccountGroup.UUID groupUUID) {
    GroupReference group = GroupReference.create(groupUUID, groupUUID.get());
    group = project.resolve(group);
    return PermissionRule.builder(group);
  }
}
