/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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
 *
 *     https://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 org.apache.jdo.tck.pc.companyAnnotatedJPA;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import org.apache.jdo.tck.pc.company.IEmployee;
import org.apache.jdo.tck.pc.company.IProject;
import org.apache.jdo.tck.util.DeepEquality;
import org.apache.jdo.tck.util.EqualityHelper;

/** This class represents a project, a budgeted task with one or more employees working on it. */
@Entity
@Table(name = "projects")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(discriminatorType = DiscriminatorType.STRING, name = "DISCRIMINATOR")
public class JPAAppProject
    implements IProject, Serializable, Comparable<IProject>, Comparator<IProject>, DeepEquality {

  private static final long serialVersionUID = 1L;

  @Id
  @Column(name = "PROJID")
  private long projid;

  @Column(name = "NAME")
  private String name;

  @Column(name = "BUDGET", length = 11, scale = 2)
  private BigDecimal budget;

  @ManyToMany(targetEntity = org.apache.jdo.tck.pc.companyAnnotatedJPA.JPAAppEmployee.class)
  @JoinTable(
      name = "project_reviewer",
      joinColumns = @JoinColumn(name = "PROJID"),
      inverseJoinColumns = @JoinColumn(name = "REVIEWER"))
  private Set<IEmployee> reviewers = new HashSet<>();

  @ManyToMany(targetEntity = org.apache.jdo.tck.pc.companyAnnotatedJPA.JPAAppEmployee.class)
  @JoinTable(
      name = "project_member",
      joinColumns = @JoinColumn(name = "PROJID"),
      inverseJoinColumns = @JoinColumn(name = "MEMBER"))
  private Set<IEmployee> members = new HashSet<>();

  /**
   * This is the JDO-required no-args constructor. The TCK relies on this constructor for testing
   * PersistenceManager.newInstance(PCClass).
   */
  public JPAAppProject() {}

  /**
   * Initialize a project.
   *
   * @param projid The project identifier.
   * @param name The name of the project.
   * @param budget The budget for the project.
   */
  public JPAAppProject(long projid, String name, BigDecimal budget) {
    this.projid = projid;
    this.name = name;
    this.budget = budget;
  }

  /**
   * Set the id associated with this object.
   *
   * @param id the id.
   */
  public void setProjid(long id) {
    if (this.projid != 0) throw new IllegalStateException("Id is already set.");
    this.projid = id;
  }

  /**
   * Get the project ID.
   *
   * @return The project ID.
   */
  public long getProjid() {
    return projid;
  }

  /**
   * Get the name of the project.
   *
   * @return The name of the project.
   */
  public String getName() {
    return name;
  }

  /**
   * Set the name of the project.
   *
   * @param name The name of the project.
   */
  public void setName(String name) {
    this.name = name;
  }

  /**
   * Get the project's budget.
   *
   * @return The project's budget.
   */
  public BigDecimal getBudget() {
    return budget;
  }

  /**
   * Set the project's budget.
   *
   * @param budget The project's budget.
   */
  public void setBudget(BigDecimal budget) {
    this.budget = budget;
  }

  /** Get the reviewers associated with this project. */
  public Set<IEmployee> getReviewers() {
    return Collections.unmodifiableSet(reviewers);
  }

  /**
   * Add a reviewer to the project.
   *
   * @param emp The employee to add as a reviewer.
   */
  public void addReviewer(JPAAppEmployee emp) {
    reviewers.add(emp);
  }

  /**
   * Remove a reviewer from the project.
   *
   * @param emp The employee to remove as a reviewer of this project.
   */
  public void removeReviewer(JPAAppEmployee emp) {
    reviewers.remove(emp);
  }

  /**
   * Set the reviewers associated with this project.
   *
   * @param reviewers The set of reviewers to associate with this project.
   */
  public void setReviewers(Set<IEmployee> reviewers) {
    // workaround: create a new HashSet, because fostore does not
    // support LinkedHashSet
    this.reviewers = (reviewers != null) ? new HashSet<>(reviewers) : null;
  }

  /**
   * Get the project members.
   *
   * @return The members of the project is returned as an unmodifiable set of <code>JPAAppEmployee
   *     </code>s.
   */
  public Set<IEmployee> getMembers() {
    return Collections.unmodifiableSet(members);
  }

  /**
   * Add a new member to the project.
   *
   * @param emp The employee to add to the project.
   */
  public void addMember(JPAAppEmployee emp) {
    members.add(emp);
  }

  /**
   * Remove a member from the project.
   *
   * @param emp The employee to remove from the project.
   */
  public void removeMember(JPAAppEmployee emp) {
    members.remove(emp);
  }

  /**
   * Set the members of the project.
   *
   * @param employees The set of employees to be the members of this project.
   */
  public void setMembers(Set<IEmployee> employees) {
    // workaround: create a new HashSet, because fostore does not
    // support LinkedHashSet
    this.members = (employees != null) ? new HashSet<>(employees) : null;
  }

  /**
   * Serialization support: initialize transient fields.
   *
   * @param in stream
   * @throws IOException error during reading
   * @throws ClassNotFoundException class could not be found
   */
  private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
    in.defaultReadObject();
    reviewers = new HashSet<>();
    members = new HashSet<>();
  }

  /**
   * Returns a String representation of a <code>JPAAppProject</code> object.
   *
   * @return a String representation of a <code>JPAAppProject</code> object.
   */
  public String toString() {
    return "JPAProject(" + getFieldRepr() + ")";
  }

  /**
   * Returns a String representation of the non-relationship fields.
   *
   * @return a String representation of the non-relationship fields.
   */
  protected String getFieldRepr() {
    StringBuilder rc = new StringBuilder();
    rc.append(projid);
    rc.append(", name ").append(name);
    rc.append(", budget ").append(budget);
    return rc.toString();
  }

  /**
   * Returns <code>true</code> if all the fields of this instance are deep equal to the coresponding
   * fields of the specified Person.
   *
   * @param other the object with which to compare.
   * @param helper EqualityHelper to keep track of instances that have already been processed.
   * @return <code>true</code> if all the fields are deep equal; <code>false</code> otherwise.
   * @throws ClassCastException if the specified instances' type prevents it from being compared to
   *     this instance.
   */
  public boolean deepCompareFields(Object other, EqualityHelper helper) {
    JPAAppProject otherProject = (JPAAppProject) other;
    String where = "JPAProject<" + projid + ">";
    return helper.equals(projid, otherProject.getProjid(), where + ".projid")
        & helper.equals(name, otherProject.getName(), where + ".name")
        & helper.equals(budget, otherProject.getBudget(), where + ".budget")
        & helper.deepEquals(reviewers, otherProject.getReviewers(), where + ".reviewers")
        & helper.deepEquals(members, otherProject.getMembers(), where + ".members");
  }

  /**
   * Compares this object with the specified JPAAppProject object for order. Returns a negative
   * integer, zero, or a positive integer as this object is less than, equal to, or greater than the
   * specified object.
   *
   * @param other The JPAAppProject object to be compared.
   * @return a negative integer, zero, or a positive integer as this object is less than, equal to,
   *     or greater than the specified JPAAppProject object.
   */
  public int compareTo(IProject other) {
    return compare(this, other);
  }

  /**
   * Compares its two IProject arguments for order. Returns a negative integer, zero, or a positive
   * integer as the first argument is less than, equal to, or greater than the second.
   *
   * @param o1 the first IProject object to be compared.
   * @param o2 the second IProject object to be compared.
   * @return a negative integer, zero, or a positive integer as the first object is less than, equal
   *     to, or greater than the second object.
   */
  public int compare(IProject o1, IProject o2) {
    return EqualityHelper.compare(o1.getProjid(), o2.getProjid());
  }

  /**
   * Indicates whether some other object is "equal to" this one.
   *
   * @param obj the object with which to compare.
   * @return <code>true</code> if this object is the same as the obj argument; <code>false</code>
   *     otherwise.
   */
  public boolean equals(Object obj) {
    if (obj instanceof JPAAppProject) {
      return compareTo((JPAAppProject) obj) == 0;
    }
    return false;
  }

  /**
   * Returns a hash code value for the object.
   *
   * @return a hash code value for this object.
   */
  public int hashCode() {
    return (int) projid;
  }

  /**
   * This class is used to represent the application identity for the <code>JPAAppProject</code>
   * class.
   */
  public static class Oid implements Serializable, Comparable<Oid> {

    private static final long serialVersionUID = 1L;

    /**
     * This field represents the identifier for the <code>JPAAppProject</code> class. It must match
     * a field in the <code>JPAAppProject</code> class in both name and type.
     */
    public long projid;

    /** The required public no-arg constructor. */
    public Oid() {}

    /**
     * Initialize the application identifier with a project ID.
     *
     * @param projid The id of the project.
     */
    public Oid(long projid) {
      this.projid = projid;
    }

    public Oid(String s) {
      projid = Long.parseLong(justTheId(s));
    }

    public String toString() {
      return this.getClass().getName() + ": " + projid;
    }

    /** */
    public boolean equals(java.lang.Object obj) {
      if (obj == null || !this.getClass().equals(obj.getClass())) return (false);
      Oid o = (Oid) obj;
      if (this.projid != o.projid) return (false);
      return (true);
    }

    /** */
    public int hashCode() {
      return ((int) projid);
    }

    protected static String justTheId(String str) {
      return str.substring(str.indexOf(':') + 1);
    }

    /** */
    public int compareTo(Oid obj) {
      return Long.compare(projid, obj.projid);
    }
  }
}
