// Copyright (C) 2016 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.server.restapi.project;

import static com.google.gerrit.server.permissions.GlobalPermission.ADMINISTRATE_SERVER;
import static com.google.gerrit.server.permissions.ProjectPermission.CREATE_REF;
import static com.google.gerrit.server.permissions.ProjectPermission.CREATE_TAG_REF;
import static com.google.gerrit.server.permissions.RefPermission.CREATE_CHANGE;
import static com.google.gerrit.server.permissions.RefPermission.READ;
import static com.google.gerrit.server.permissions.RefPermission.WRITE_CONFIG;
import static java.util.stream.Collectors.toMap;

import com.google.common.collect.ImmutableBiMap;
import com.google.common.collect.Iterables;
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.common.data.AccessSection;
import com.google.gerrit.common.data.GroupDescription;
import com.google.gerrit.common.data.Permission;
import com.google.gerrit.common.data.PermissionRule;
import com.google.gerrit.common.data.RefConfigSection;
import com.google.gerrit.extensions.api.access.AccessSectionInfo;
import com.google.gerrit.extensions.api.access.PermissionInfo;
import com.google.gerrit.extensions.api.access.PermissionRuleInfo;
import com.google.gerrit.extensions.api.access.ProjectAccessInfo;
import com.google.gerrit.extensions.common.GroupInfo;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
import com.google.gerrit.extensions.restapi.RestReadView;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.WebLinks;
import com.google.gerrit.server.account.GroupBackend;
import com.google.gerrit.server.config.AllProjectsName;
import com.google.gerrit.server.git.meta.MetaDataUpdate;
import com.google.gerrit.server.permissions.GlobalPermission;
import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.server.permissions.ProjectPermission;
import com.google.gerrit.server.permissions.RefPermission;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectConfig;
import com.google.gerrit.server.project.ProjectJson;
import com.google.gerrit.server.project.ProjectResource;
import com.google.gerrit.server.project.ProjectState;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.errors.RepositoryNotFoundException;

@Singleton
public class GetAccess implements RestReadView<ProjectResource> {
  private static final FluentLogger logger = FluentLogger.forEnclosingClass();

  public static final ImmutableBiMap<PermissionRule.Action, PermissionRuleInfo.Action> ACTION_TYPE =
      ImmutableBiMap.of(
          PermissionRule.Action.ALLOW,
          PermissionRuleInfo.Action.ALLOW,
          PermissionRule.Action.BATCH,
          PermissionRuleInfo.Action.BATCH,
          PermissionRule.Action.BLOCK,
          PermissionRuleInfo.Action.BLOCK,
          PermissionRule.Action.DENY,
          PermissionRuleInfo.Action.DENY,
          PermissionRule.Action.INTERACTIVE,
          PermissionRuleInfo.Action.INTERACTIVE);

  private final Provider<CurrentUser> user;
  private final PermissionBackend permissionBackend;
  private final AllProjectsName allProjectsName;
  private final ProjectJson projectJson;
  private final ProjectCache projectCache;
  private final MetaDataUpdate.Server metaDataUpdateFactory;
  private final GroupBackend groupBackend;
  private final WebLinks webLinks;
  private final ProjectConfig.Factory projectConfigFactory;

  @Inject
  public GetAccess(
      Provider<CurrentUser> self,
      PermissionBackend permissionBackend,
      AllProjectsName allProjectsName,
      ProjectCache projectCache,
      MetaDataUpdate.Server metaDataUpdateFactory,
      ProjectJson projectJson,
      GroupBackend groupBackend,
      WebLinks webLinks,
      ProjectConfig.Factory projectConfigFactory) {
    this.user = self;
    this.permissionBackend = permissionBackend;
    this.allProjectsName = allProjectsName;
    this.projectJson = projectJson;
    this.projectCache = projectCache;
    this.metaDataUpdateFactory = metaDataUpdateFactory;
    this.groupBackend = groupBackend;
    this.webLinks = webLinks;
    this.projectConfigFactory = projectConfigFactory;
  }

  public ProjectAccessInfo apply(Project.NameKey nameKey)
      throws ResourceNotFoundException, ResourceConflictException, IOException,
          PermissionBackendException {
    ProjectState state = projectCache.checkedGet(nameKey);
    if (state == null) {
      throw new ResourceNotFoundException(nameKey.get());
    }
    return apply(new ProjectResource(state, user.get()));
  }

  @Override
  public ProjectAccessInfo apply(ProjectResource rsrc)
      throws ResourceNotFoundException, ResourceConflictException, IOException,
          PermissionBackendException {
    // Load the current configuration from the repository, ensuring it's the most
    // recent version available. If it differs from what was in the project
    // state, force a cache flush now.

    Project.NameKey projectName = rsrc.getNameKey();
    ProjectAccessInfo info = new ProjectAccessInfo();
    ProjectState projectState = projectCache.checkedGet(projectName);
    PermissionBackend.ForProject perm = permissionBackend.currentUser().project(projectName);

    ProjectConfig config;
    try (MetaDataUpdate md = metaDataUpdateFactory.create(projectName)) {
      config = projectConfigFactory.read(md);
      info.configWebLinks = new ArrayList<>();

      // config may have a null revision if the repo doesn't have its own refs/meta/config.
      if (config.getRevision() != null) {
        info.configWebLinks.addAll(
            webLinks.getFileHistoryLinks(
                projectName.get(), config.getRevision().getName(), ProjectConfig.PROJECT_CONFIG));
      }

      if (config.updateGroupNames(groupBackend)) {
        md.setMessage("Update group names\n");
        config.commit(md);
        projectCache.evict(config.getProject());
        projectState = projectCache.checkedGet(projectName);
        perm = permissionBackend.currentUser().project(projectName);
      } else if (config.getRevision() != null
          && !config.getRevision().equals(projectState.getConfig().getRevision())) {
        projectCache.evict(config.getProject());
        projectState = projectCache.checkedGet(projectName);
        perm = permissionBackend.currentUser().project(projectName);
      }
    } catch (ConfigInvalidException e) {
      throw new ResourceConflictException(e.getMessage());
    } catch (RepositoryNotFoundException e) {
      throw new ResourceNotFoundException(rsrc.getName());
    }

    // The following implementation must match the ProjectAccessFactory JSON RPC endpoint.

    info.local = new HashMap<>();
    info.ownerOf = new HashSet<>();
    Map<AccountGroup.UUID, GroupInfo> groups = new HashMap<>();
    boolean canReadConfig = check(perm, RefNames.REFS_CONFIG, READ);
    boolean canWriteConfig = check(perm, ProjectPermission.WRITE_CONFIG);

    // Check if the project state permits read only when the user is not allowed to write the config
    // (=owner). This is so that the owner can still read (and in the next step write) the project's
    // config to set the project state to any state that is not HIDDEN.
    if (!canWriteConfig) {
      projectState.checkStatePermitsRead();
    }

    for (AccessSection section : config.getAccessSections()) {
      String name = section.getName();
      if (AccessSection.GLOBAL_CAPABILITIES.equals(name)) {
        if (canWriteConfig) {
          info.local.put(name, createAccessSection(groups, section));
          info.ownerOf.add(name);

        } else if (canReadConfig) {
          info.local.put(section.getName(), createAccessSection(groups, section));
        }

      } else if (RefConfigSection.isValid(name)) {
        if (check(perm, name, WRITE_CONFIG)) {
          info.local.put(name, createAccessSection(groups, section));
          info.ownerOf.add(name);

        } else if (canReadConfig) {
          info.local.put(name, createAccessSection(groups, section));

        } else if (check(perm, name, READ)) {
          // Filter the section to only add rules describing groups that
          // are visible to the current-user. This includes any group the
          // user is a member of, as well as groups they own or that
          // are visible to all users.

          AccessSection dst = null;
          for (Permission srcPerm : section.getPermissions()) {
            Permission dstPerm = null;

            for (PermissionRule srcRule : srcPerm.getRules()) {
              AccountGroup.UUID groupId = srcRule.getGroup().getUUID();
              if (groupId == null) {
                continue;
              }

              loadGroup(groups, groupId);
              if (dstPerm == null) {
                if (dst == null) {
                  dst = new AccessSection(name);
                  info.local.put(name, createAccessSection(groups, dst));
                }
                dstPerm = dst.getPermission(srcPerm.getName(), true);
              }
              dstPerm.add(srcRule);
            }
          }
        }
      }
    }

    if (info.ownerOf.isEmpty()) {
      try {
        permissionBackend.currentUser().check(GlobalPermission.ADMINISTRATE_SERVER);
        // Special case: If the section list is empty, this project has no current
        // access control information. Fall back to site administrators.
        info.ownerOf.add(AccessSection.ALL);
      } catch (AuthException e) {
        // Do nothing.
      }
    }

    if (config.getRevision() != null) {
      info.revision = config.getRevision().name();
    }

    ProjectState parent = Iterables.getFirst(projectState.parents(), null);
    if (parent != null) {
      info.inheritsFrom = projectJson.format(parent.getProject());
    }

    if (projectName.equals(allProjectsName)
        && permissionBackend.currentUser().testOrFalse(ADMINISTRATE_SERVER)) {
      info.ownerOf.add(AccessSection.GLOBAL_CAPABILITIES);
    }

    info.isOwner = toBoolean(canWriteConfig);
    info.canUpload =
        toBoolean(
            projectState.statePermitsWrite()
                && (canWriteConfig
                    || (canReadConfig
                        && perm.ref(RefNames.REFS_CONFIG).testOrFalse(CREATE_CHANGE))));
    info.canAdd = toBoolean(perm.testOrFalse(CREATE_REF));
    info.canAddTags = toBoolean(perm.testOrFalse(CREATE_TAG_REF));
    info.configVisible = canReadConfig || canWriteConfig;

    info.groups =
        groups
            .entrySet()
            .stream()
            .filter(e -> e.getValue() != null)
            .collect(toMap(e -> e.getKey().get(), Map.Entry::getValue));

    return info;
  }

  private void loadGroup(Map<AccountGroup.UUID, GroupInfo> groups, AccountGroup.UUID id) {
    if (!groups.containsKey(id)) {
      GroupDescription.Basic basic = groupBackend.get(id);
      GroupInfo group;
      if (basic != null) {
        group = new GroupInfo();
        // The UI only needs name + URL, so don't populate other fields to avoid leaking data
        // about groups invisible to the user.
        group.name = basic.getName();
        group.url = basic.getUrl();
      } else {
        logger.atWarning().log("no such group: %s", id);
        group = null;
      }
      groups.put(id, group);
    }
  }

  private static boolean check(PermissionBackend.ForProject ctx, String ref, RefPermission perm)
      throws PermissionBackendException {
    try {
      ctx.ref(ref).check(perm);
      return true;
    } catch (AuthException denied) {
      return false;
    }
  }

  private static boolean check(PermissionBackend.ForProject ctx, ProjectPermission perm)
      throws PermissionBackendException {
    try {
      ctx.check(perm);
      return true;
    } catch (AuthException denied) {
      return false;
    }
  }

  private AccessSectionInfo createAccessSection(
      Map<AccountGroup.UUID, GroupInfo> groups, AccessSection section) {
    AccessSectionInfo accessSectionInfo = new AccessSectionInfo();
    accessSectionInfo.permissions = new HashMap<>();
    for (Permission p : section.getPermissions()) {
      PermissionInfo pInfo = new PermissionInfo(p.getLabel(), p.getExclusiveGroup() ? true : null);
      pInfo.rules = new HashMap<>();
      for (PermissionRule r : p.getRules()) {
        PermissionRuleInfo info =
            new PermissionRuleInfo(ACTION_TYPE.get(r.getAction()), r.getForce());
        if (r.hasRange()) {
          info.max = r.getMax();
          info.min = r.getMin();
        }
        AccountGroup.UUID group = r.getGroup().getUUID();
        if (group != null) {
          pInfo.rules.put(group.get(), info);
          loadGroup(groups, group);
        }
      }
      accessSectionInfo.permissions.put(p.getName(), pInfo);
    }
    return accessSectionInfo;
  }

  private static Boolean toBoolean(boolean value) {
    return value ? true : null;
  }
}
