// Copyright (C) 2014 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.googlesource.gerrit.plugins.gitblit.auth;

import com.gitblit.Constants.AccessPermission;
import com.gitblit.Constants.AccessRestrictionType;
import com.gitblit.models.RepositoryModel;
import com.gitblit.models.TeamModel;
import com.gitblit.models.UserModel;
import com.gitblit.utils.StringUtils;
import com.google.gerrit.extensions.client.ProjectState;
import com.google.gerrit.reviewdb.client.Project.NameKey;
import com.google.gerrit.server.project.NoSuchProjectException;
import com.google.gerrit.server.project.ProjectControl;
import com.google.gerrit.server.project.ProjectControl.Factory;
import java.util.HashSet;
import java.util.Set;

public class GerritToGitBlitUserModel extends UserModel {
  public static final String ANONYMOUS_USER = "$anonymous";
  public static final char[] ANONYMOUS_PASSWORD = ANONYMOUS_USER.toCharArray();

  private static final long serialVersionUID = 1L;

  // field names are reflectively mapped in EditUser page
  public String username;
  public String password;
  public String cookie;
  public String displayName;
  public String emailAddress;
  public boolean canAdmin;
  public boolean excludeFromFederation;
  public final Set<String> repositories = new HashSet<String>();
  public final Set<TeamModel> teams = new HashSet<TeamModel>();

  private final transient ProjectControl.Factory projectControlFactory;

  // non-persisted fields
  public boolean isAuthenticated;

  public GerritToGitBlitUserModel(String username) {
    this(username, null);
  }

  public GerritToGitBlitUserModel(String username, ProjectControl.Factory projectControlFactory) {
    super(username);
    this.username = username;
    this.isAuthenticated = true;
    this.projectControlFactory = projectControlFactory;
  }

  public GerritToGitBlitUserModel(ProjectControl.Factory projectControlFactory) {
    super(ANONYMOUS_USER);
    this.projectControlFactory = projectControlFactory;
  }

  @Deprecated
  public boolean canAccessRepository(String repositoryName) {
    boolean result = false;

    try {
      ProjectControl control = projectControlFactory.controlFor(new NameKey(repositoryName));
      result = control != null;
    } catch (NoSuchProjectException e) {
      result = false;
    }

    return result;
  }

  @Override
  protected boolean canAccess(
      RepositoryModel repository,
      AccessRestrictionType ifRestriction,
      AccessPermission requirePermission) {
    boolean result = false;

    try {
      ProjectControl control =
          projectControlFactory.controlFor(new NameKey(getRepositoryName(repository.name)));

      if (control == null) {
        return false;
      }

      switch (ifRestriction) {
        case VIEW:
          return !control.getProject().getState().equals(ProjectState.HIDDEN);
        case CLONE:
          return control.canRunUploadPack();
        case PUSH:
          return control.canRunReceivePack();
        default:
          return true;
      }
    } catch (NoSuchProjectException e) {
      result = false;
    }

    return result;
  }

  public String getRepositoryName(String name) {
    if (name.endsWith(".git")) {
      name = name.substring(0, name.length() - 4);
    }
    return name;
  }

  @Override
  public boolean hasRepositoryPermission(String name) {
    boolean result = false;

    try {
      name = getRepositoryName(name);
      ProjectControl control = projectControlFactory.controlFor(new NameKey(name));
      result = control != null && !control.getProject().getState().equals(ProjectState.HIDDEN);
    } catch (NoSuchProjectException e) {
      result = false;
    }

    return result;
  }

  public boolean hasTeamAccess(String repositoryName) {
    for (TeamModel team : teams) {
      if (team.hasRepositoryPermission(repositoryName)) {
        return true;
      }
    }
    return false;
  }

  public boolean hasRepository(String name) {
    return repositories.contains(name.toLowerCase());
  }

  public void addRepository(String name) {
    repositories.add(name.toLowerCase());
  }

  public void removeRepository(String name) {
    repositories.remove(name.toLowerCase());
  }

  public boolean isTeamMember(String teamname) {
    for (TeamModel team : teams) {
      if (team.name.equalsIgnoreCase(teamname)) {
        return true;
      }
    }
    return false;
  }

  public TeamModel getTeam(String teamname) {
    if (teams == null) {
      return null;
    }
    for (TeamModel team : teams) {
      if (team.name.equalsIgnoreCase(teamname)) {
        return team;
      }
    }
    return null;
  }

  @Override
  public String getName() {
    return username;
  }

  public String getDisplayName() {
    if (StringUtils.isEmpty(displayName)) {
      return username;
    }
    return displayName;
  }

  @Override
  public String toString() {
    return username;
  }

  @Override
  public int compareTo(UserModel o) {
    return username.compareTo(o.username);
  }

  public static UserModel getAnonymous(Factory projectControl) {
    return new GerritToGitBlitUserModel(ANONYMOUS_USER, projectControl);
  }
}
