// Copyright (C) 2010 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.schema;

import static com.google.gerrit.common.data.Permission.CREATE;
import static com.google.gerrit.common.data.Permission.FORGE_AUTHOR;
import static com.google.gerrit.common.data.Permission.FORGE_COMMITTER;
import static com.google.gerrit.common.data.Permission.FORGE_SERVER;
import static com.google.gerrit.common.data.Permission.LABEL;
import static com.google.gerrit.common.data.Permission.OWNER;
import static com.google.gerrit.common.data.Permission.PUSH;
import static com.google.gerrit.common.data.Permission.PUSH_MERGE;
import static com.google.gerrit.common.data.Permission.PUSH_TAG;
import static com.google.gerrit.common.data.Permission.READ;
import static com.google.gerrit.common.data.Permission.SUBMIT;

import com.google.gerrit.common.data.AccessSection;
import com.google.gerrit.common.data.GroupReference;
import com.google.gerrit.common.data.Permission;
import com.google.gerrit.common.data.PermissionRule;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.ApprovalCategory;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.SystemConfig;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.GerritPersonIdent;
import com.google.gerrit.server.account.GroupUUID;
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.MetaDataUpdate;
import com.google.gerrit.server.git.ProjectConfig;
import com.google.gwtorm.jdbc.JdbcSchema;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.Provider;

import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.Repository;

import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

class Schema_53 extends SchemaVersion {
  private final GitRepositoryManager mgr;
  private final PersonIdent serverUser;

  private SystemConfig systemConfig;
  private Map<AccountGroup.Id, GroupReference> groupMap;
  private Map<ApprovalCategory.Id, ApprovalCategory> categoryMap;
  private GroupReference projectOwners;

  private Map<Project.NameKey, Project.NameKey> parentsByProject;
  private Map<Project.NameKey, List<OldRefRight>> rightsByProject;

  private final String OLD_SUBMIT = "SUBM";
  private final String OLD_READ = "READ";
  private final String OLD_OWN = "OWN";
  private final String OLD_PUSH_TAG = "pTAG";
  private final String OLD_PUSH_HEAD = "pHD";
  private final String OLD_FORGE_IDENTITY = "FORG";

  @Inject
  Schema_53(Provider<Schema_52> prior, GitRepositoryManager mgr,
      @GerritPersonIdent PersonIdent serverUser) {
    super(prior);
    this.mgr = mgr;
    this.serverUser = serverUser;
  }

  @Override
  protected void migrateData(ReviewDb db, UpdateUI ui) throws OrmException,
      SQLException {
    systemConfig = db.systemConfig().get(new SystemConfig.Key());
    categoryMap = db.approvalCategories().toMap(db.approvalCategories().all());

    assignGroupUUIDs(db);
    readOldRefRights(db);
    readProjectParents(db);
    exportProjectConfig(db);

    deleteActionCategories(db);
  }

  private void deleteActionCategories(ReviewDb db) throws OrmException {
    List<ApprovalCategory> delete = new ArrayList<ApprovalCategory>();
    for (ApprovalCategory category : categoryMap.values()) {
      if (category.getPosition() < 0) {
        delete.add(category);
      }
    }
    db.approvalCategories().delete(delete);
  }

  private void assignGroupUUIDs(ReviewDb db) throws OrmException {
    groupMap = new HashMap<AccountGroup.Id, GroupReference>();
    List<AccountGroup> groups = db.accountGroups().all().toList();
    for (AccountGroup g : groups) {
      if (g.getId().equals(systemConfig.ownerGroupId)) {
        g.setGroupUUID(AccountGroup.PROJECT_OWNERS);
        projectOwners = GroupReference.forGroup(g);

      } else if (g.getId().equals(systemConfig.anonymousGroupId)) {
        g.setGroupUUID(AccountGroup.ANONYMOUS_USERS);

      } else if (g.getId().equals(systemConfig.registeredGroupId)) {
        g.setGroupUUID(AccountGroup.REGISTERED_USERS);

      } else {
        g.setGroupUUID(GroupUUID.make(g.getName(), serverUser));
      }
      groupMap.put(g.getId(), GroupReference.forGroup(g));
    }
    db.accountGroups().update(groups);

    systemConfig.adminGroupUUID = toUUID(systemConfig.adminGroupId);
    systemConfig.batchUsersGroupUUID = toUUID(systemConfig.batchUsersGroupId);
    db.systemConfig().update(Collections.singleton(systemConfig));
  }

  private AccountGroup.UUID toUUID(AccountGroup.Id id) {
    return groupMap.get(id).getUUID();
  }

  private void exportProjectConfig(ReviewDb db) throws OrmException,
      SQLException {
    Statement stmt = ((JdbcSchema) db).getConnection().createStatement();
    ResultSet rs = stmt.executeQuery("SELECT * FROM projects ORDER BY name");
    while (rs.next()) {
      final String name = rs.getString("name");
      final Project.NameKey nameKey = new Project.NameKey(name);

      Repository git;
      try {
        git = mgr.openRepository(nameKey);
      } catch (RepositoryNotFoundException notFound) {
        // A repository may be missing if this project existed only to store
        // inheritable permissions. For example 'All-Projects'.
        try {
          git = mgr.createRepository(nameKey);
        } catch (IOException err) {
          throw new OrmException("Cannot create repository " + name, err);
        }
      } catch (IOException e) {
        throw new OrmException(e);
      }
      try {
        MetaDataUpdate md =
            new MetaDataUpdate(GitReferenceUpdated.DISABLED, nameKey, git);
        md.getCommitBuilder().setAuthor(serverUser);
        md.getCommitBuilder().setCommitter(serverUser);

        ProjectConfig config = ProjectConfig.read(md);
        loadProject(rs, config.getProject());
        config.getAccessSections().clear();
        convertRights(config);

        // Grant out read on the config branch by default.
        //
        if (config.getProject().getNameKey().equals(systemConfig.wildProjectName)) {
          AccessSection meta = config.getAccessSection(GitRepositoryManager.REF_CONFIG, true);
          Permission read = meta.getPermission(READ, true);
          read.getRule(config.resolve(projectOwners), true);
        }

        md.setMessage("Import project configuration from SQL\n");
        config.commit(md);
      } catch (ConfigInvalidException err) {
        throw new OrmException("Cannot read project " + name, err);
      } catch (IOException err) {
        throw new OrmException("Cannot export project " + name, err);
      } finally {
        git.close();
      }
    }
    rs.close();
    stmt.close();
  }

  private void loadProject(ResultSet rs, Project project) throws SQLException,
      OrmException {
    project.setDescription(rs.getString("description"));
    project.setUseContributorAgreements("Y".equals(rs
        .getString("use_contributor_agreements")));

    switch (rs.getString("submit_type").charAt(0)) {
      case 'F':
        project.setSubmitType(Project.SubmitType.FAST_FORWARD_ONLY);
        break;
      case 'M':
        project.setSubmitType(Project.SubmitType.MERGE_IF_NECESSARY);
        break;
      case 'A':
        project.setSubmitType(Project.SubmitType.MERGE_ALWAYS);
        break;
      case 'C':
        project.setSubmitType(Project.SubmitType.CHERRY_PICK);
        break;
      default:
        throw new OrmException("Unsupported submit_type="
            + rs.getString("submit_type") + " on project " + project.getName());
    }

    project.setUseSignedOffBy("Y".equals(rs.getString("use_signed_off_by")));
    project.setRequireChangeID("Y".equals(rs.getString("require_change_id")));
    project.setUseContentMerge("Y".equals(rs.getString("use_content_merge")));
    project.setParentName(rs.getString("parent_name"));
  }

  private void readOldRefRights(ReviewDb db) throws SQLException {
    rightsByProject = new HashMap<Project.NameKey, List<OldRefRight>>();

    Statement stmt = ((JdbcSchema) db).getConnection().createStatement();
    ResultSet rs = stmt.executeQuery("SELECT * FROM ref_rights");
    while (rs.next()) {
      OldRefRight right = new OldRefRight(rs);
      if (right.group == null || right.category == null) {
        continue;
      }

      List<OldRefRight> list;

      list = rightsByProject.get(right.project);
      if (list == null) {
        list = new ArrayList<OldRefRight>();
        rightsByProject.put(right.project, list);
      }
      list.add(right);
    }
    rs.close();
    stmt.close();
  }

  private void readProjectParents(ReviewDb db) throws SQLException {
    parentsByProject = new HashMap<Project.NameKey, Project.NameKey>();
    Statement stmt = ((JdbcSchema) db).getConnection().createStatement();
    ResultSet rs = stmt.executeQuery("SELECT * FROM projects");
    while (rs.next()) {
      String name = rs.getString("name");
      String parent_name = rs.getString("parent_name");
      if (parent_name == null) {
        parent_name = systemConfig.wildProjectName.get();
      }
      parentsByProject.put(new Project.NameKey(name), //
          new Project.NameKey(parent_name));
    }
    rs.close();
    stmt.close();
  }

  private void convertRights(ProjectConfig config) {
    List<OldRefRight> myRights =
        rightsByProject.get(config.getProject().getNameKey());
    if (myRights == null) {
      return;
    }

    for (OldRefRight old : myRights) {
      AccessSection section = config.getAccessSection(old.ref_pattern, true);
      GroupReference group = config.resolve(old.group);

      if (OLD_SUBMIT.equals(old.category)) {
        PermissionRule submit = rule(group);
        if (old.max_value <= 0) {
          submit.setDeny();
        }
        add(section, SUBMIT, old.exclusive, submit);

      } else if (OLD_READ.equals(old.category)) {
        if (old.exclusive) {
          section.getPermission(READ, true).setExclusiveGroup(true);
          newChangePermission(config, old.ref_pattern).setExclusiveGroup(true);
        }

        PermissionRule read = rule(group);
        if (old.max_value <= 0) {
          read.setDeny();
        }
        add(section, READ, old.exclusive, read);

        if (3 <= old.max_value) {
          newMergePermission(config, old.ref_pattern).add(rule(group));
        } else if (3 <= inheritedMax(config, old)) {
          newMergePermission(config, old.ref_pattern).add(deny(group));
        }

        if (2 <= old.max_value) {
          newChangePermission(config, old.ref_pattern).add(rule(group));
        } else if (2 <= inheritedMax(config, old)) {
          newChangePermission(config, old.ref_pattern).add(deny(group));
        }

      } else if (OLD_OWN.equals(old.category)) {
        add(section, OWNER, false, rule(group));

      } else if (OLD_PUSH_TAG.equals(old.category)) {
        PermissionRule push = rule(group);
        if (old.max_value <= 0) {
          push.setDeny();
        }
        add(section, PUSH_TAG, old.exclusive, push);

      } else if (OLD_PUSH_HEAD.equals(old.category)) {
        if (old.exclusive) {
          section.getPermission(PUSH, true).setExclusiveGroup(true);
          section.getPermission(CREATE, true).setExclusiveGroup(true);
        }

        PermissionRule push = rule(group);
        if (old.max_value <= 0) {
          push.setDeny();
        }
        push.setForce(3 <= old.max_value);
        add(section, PUSH, old.exclusive, push);

        if (2 <= old.max_value) {
          add(section, CREATE, old.exclusive, rule(group));
        } else if (2 <= inheritedMax(config, old)) {
          add(section, CREATE, old.exclusive, deny(group));
        }

      } else if (OLD_FORGE_IDENTITY.equals(old.category)) {
        if (old.exclusive) {
          section.getPermission(FORGE_AUTHOR, true).setExclusiveGroup(true);
          section.getPermission(FORGE_COMMITTER, true).setExclusiveGroup(true);
          section.getPermission(FORGE_SERVER, true).setExclusiveGroup(true);
        }

        if (1 <= old.max_value) {
          add(section, FORGE_AUTHOR, old.exclusive, rule(group));
        }

        if (2 <= old.max_value) {
          add(section, FORGE_COMMITTER, old.exclusive, rule(group));
        } else if (2 <= inheritedMax(config, old)) {
          add(section, FORGE_COMMITTER, old.exclusive, deny(group));
        }

        if (3 <= old.max_value) {
          add(section, FORGE_SERVER, old.exclusive, rule(group));
        } else if (3 <= inheritedMax(config, old)) {
          add(section, FORGE_SERVER, old.exclusive, deny(group));
        }

      } else {
        PermissionRule rule = rule(group);
        rule.setRange(old.min_value, old.max_value);
        if (old.min_value == 0 && old.max_value == 0) {
          rule.setDeny();
        }
        add(section, LABEL + varNameOf(old.category), old.exclusive, rule);
      }
    }
  }

  private static Permission newChangePermission(ProjectConfig config,
      String name) {
    if (name.startsWith(AccessSection.REGEX_PREFIX)) {
      name = AccessSection.REGEX_PREFIX
          + "refs/for/"
          + name.substring(AccessSection.REGEX_PREFIX.length());
    } else {
      name = "refs/for/" + name;
    }
    return config.getAccessSection(name, true).getPermission(PUSH, true);
  }

  private static Permission newMergePermission(ProjectConfig config,
      String name) {
    if (name.startsWith(AccessSection.REGEX_PREFIX)) {
      name = AccessSection.REGEX_PREFIX
          + "refs/for/"
          + name.substring(AccessSection.REGEX_PREFIX.length());
    } else {
      name = "refs/for/" + name;
    }
    return config.getAccessSection(name, true).getPermission(PUSH_MERGE, true);
  }

  private static PermissionRule rule(GroupReference group) {
    return new PermissionRule(group);
  }

  private static PermissionRule deny(GroupReference group) {
    PermissionRule rule = rule(group);
    rule.setDeny();
    return rule;
  }

  private int inheritedMax(ProjectConfig config, OldRefRight old) {
    int max = 0;

    String ref = old.ref_pattern;
    String category = old.category;
    AccountGroup.UUID group = old.group.getUUID();

    Project.NameKey project = config.getProject().getParent();
    if (project == null) {
      project = systemConfig.wildProjectName;
    }
    do {
      List<OldRefRight> rights = rightsByProject.get(project);
      if (rights != null) {
        for (OldRefRight r : rights) {
          if (r.ref_pattern.equals(ref) //
              && r.group.getUUID().equals(group) //
              && r.category.equals(category)) {
            max = Math.max(max, r.max_value);
            break;
          }
        }
      }
      project = parentsByProject.get(project);
    } while (!project.equals(systemConfig.wildProjectName));

    return max;
  }

  private String varNameOf(String id) {
    ApprovalCategory category = categoryMap.get(new ApprovalCategory.Id(id));
    if (category == null) {
      category = new ApprovalCategory(new ApprovalCategory.Id(id), id);
    }
    return category.getLabelName();
  }

  private static void add(AccessSection section, String name,
      boolean exclusive, PermissionRule rule) {
    Permission p = section.getPermission(name, true);
    if (exclusive) {
      p.setExclusiveGroup(true);
    }
    p.add(rule);
  }

  private class OldRefRight {
    final int min_value;
    final int max_value;
    final String ref_pattern;
    final boolean exclusive;
    final GroupReference group;
    final String category;
    final Project.NameKey project;

    OldRefRight(ResultSet rs) throws SQLException {
      min_value = rs.getInt("min_value");
      max_value = rs.getInt("max_value");
      project = new Project.NameKey(rs.getString("project_name"));

      String r = rs.getString("ref_pattern");
      exclusive = r.startsWith("-");
      if (exclusive) {
        r = r.substring(1);
      }
      ref_pattern = r;

      category = rs.getString("category_id");
      group = groupMap.get(new AccountGroup.Id(rs.getInt("group_id")));
    }
  }
}
