// Copyright (C) 2008 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.reviewdb;

import com.google.gwtorm.client.Column;
import com.google.gwtorm.client.IntKey;
import com.google.gwtorm.client.StringKey;

/** Named group of one or more accounts, typically used for access controls. */
public final class AccountGroup {
  /** Group name key */
  public static class NameKey extends
      StringKey<com.google.gwtorm.client.Key<?>> {
    private static final long serialVersionUID = 1L;

    @Column(id = 1)
    protected String name;

    protected NameKey() {
    }

    public NameKey(final String n) {
      name = n;
    }

    @Override
    public String get() {
      return name;
    }

    @Override
    protected void set(String newValue) {
      name = newValue;
    }
  }

  /** Distinguished name, within organization directory server. */
  public static class ExternalNameKey extends
      StringKey<com.google.gwtorm.client.Key<?>> {
    private static final long serialVersionUID = 1L;

    @Column(id = 1)
    protected String name;

    protected ExternalNameKey() {
    }

    public ExternalNameKey(final String n) {
      name = n;
    }

    @Override
    public String get() {
      return name;
    }

    @Override
    protected void set(String newValue) {
      name = newValue;
    }
  }

  /** Synthetic key to link to within the database */
  public static class Id extends IntKey<com.google.gwtorm.client.Key<?>> {
    private static final long serialVersionUID = 1L;

    @Column(id = 1)
    protected int id;

    protected Id() {
    }

    public Id(final int id) {
      this.id = id;
    }

    @Override
    public int get() {
      return id;
    }

    @Override
    protected void set(int newValue) {
      id = newValue;
    }

    /** Parse an AccountGroup.Id out of a string representation. */
    public static Id parse(final String str) {
      final Id r = new Id();
      r.fromString(str);
      return r;
    }
  }

  public static enum Type {
    /**
     * System defined and managed group, e.g. anonymous users.
     * <p>
     * These groups must be explicitly named by {@link SystemConfig} and are
     * specially handled throughout the code. In UI contexts their membership is
     * not displayed. When computing effective group membership for any given
     * user account, these groups are automatically handled using specialized
     * branch conditions.
     */
    SYSTEM,

    /**
     * Group defined within our database.
     * <p>
     * An internal group has its membership fully enumerated in the database.
     * The membership can be viewed and edited through the web UI by any user
     * who is a member of the owner group. These groups are not treated special
     * in the code.
     */
    INTERNAL,

    /**
     * Group defined by external LDAP database.
     * <p>
     * A group whose membership is determined by the LDAP directory that we
     * connect to for user and group information. In UI contexts the membership
     * of the group is not displayed, as it may be exceedingly large, or might
     * contain users who have never logged into this server before (and thus
     * have no matching account record). Adding or removing users from an LDAP
     * group requires making edits through the LDAP directory, and cannot be
     * done through our UI.
     */
    LDAP;
  }

  /** Unique name of this group within the system. */
  @Column(id = 1)
  protected NameKey name;

  /** Unique identity, to link entities as {@link #name} can change. */
  @Column(id = 2)
  protected Id groupId;

  /**
   * Identity of the group whose members can manage this group.
   * <p>
   * This can be a self-reference to indicate the group's members manage itself.
   */
  @Column(id = 3)
  protected Id ownerGroupId;

  /** A textual description of the group's purpose. */
  @Column(id = 4, length = Integer.MAX_VALUE, notNull = false)
  protected String description;

  /** Is the membership managed by some external means? */
  @Column(id = 5, length = 8)
  protected String groupType;

  /** Distinguished name in the directory server. */
  @Column(id = 6, notNull = false)
  protected ExternalNameKey externalName;

  protected AccountGroup() {
  }

  public AccountGroup(final AccountGroup.NameKey newName,
      final AccountGroup.Id newId) {
    name = newName;
    groupId = newId;
    ownerGroupId = groupId;
    setType(Type.INTERNAL);
  }

  public AccountGroup.Id getId() {
    return groupId;
  }

  public String getName() {
    return name.get();
  }

  public AccountGroup.NameKey getNameKey() {
    return name;
  }

  public void setNameKey(final AccountGroup.NameKey nameKey) {
    name = nameKey;
  }

  public String getDescription() {
    return description;
  }

  public void setDescription(final String d) {
    description = d;
  }

  public AccountGroup.Id getOwnerGroupId() {
    return ownerGroupId;
  }

  public void setOwnerGroupId(final AccountGroup.Id id) {
    ownerGroupId = id;
  }

  public Type getType() {
    return Type.valueOf(groupType);
  }

  public void setType(final Type t) {
    groupType = t.name();
  }

  public ExternalNameKey getExternalNameKey() {
    return externalName;
  }

  public void setExternalNameKey(final ExternalNameKey k) {
    externalName = k;
  }
}
