// Copyright (C) 2012 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.common.data;

import com.google.gerrit.reviewdb.client.Project;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/** Portion of a {@link Project} describing a single contributor agreement. */
public class ContributorAgreement implements Comparable<ContributorAgreement> {
  protected String name;
  protected String description;
  protected List<PermissionRule> accepted;
  protected boolean requireContactInformation;
  protected GroupReference autoVerify;
  protected String agreementUrl;

  protected ContributorAgreement() {
  }

  public ContributorAgreement(String name) {
    setName(name);
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public String getDescription() {
    return description;
  }

  public void setDescription(String description) {
    this.description = description;
  }

  public List<PermissionRule> getAccepted() {
    if (accepted == null) {
      accepted = new ArrayList<PermissionRule>();
    }
    return accepted;
  }

  public void setAccepted(List<PermissionRule> accepted) {
    this.accepted = accepted;
  }

  public boolean isRequireContactInformation() {
    return requireContactInformation;
  }

  public void setRequireContactInformation(boolean requireContactInformation) {
    this.requireContactInformation = requireContactInformation;
  }

  public GroupReference getAutoVerify() {
    return autoVerify;
  }

  public void setAutoVerify(GroupReference autoVerify) {
    this.autoVerify = autoVerify;
  }

  public String getAgreementUrl() {
    return agreementUrl;
  }

  public void setAgreementUrl(String agreementUrl) {
    this.agreementUrl = agreementUrl;
  }

  @Override
  public int compareTo(ContributorAgreement o) {
    return getName().compareTo(o.getName());
  }

  @Override
  public String toString() {
    return "ContributorAgreement[" + getName() + "]";
  }

  public ContributorAgreement forUi() {
    ContributorAgreement ca = new ContributorAgreement(name);
    ca.description = description;
    ca.accepted = Collections.emptyList();
    ca.requireContactInformation = requireContactInformation;
    if (autoVerify != null) {
      ca.autoVerify = new GroupReference();
    }
    ca.agreementUrl = agreementUrl ;
    return ca;
  }
}
