/*
 * 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
<<<<<<< Updated upstream
 *
 *     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
=======
 * 
 *     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 
>>>>>>> Stashed changes
 * limitations under the License.
 */

package org.apache.jdo.tck.pc.companyMapWithoutJoin;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import org.apache.jdo.tck.util.DeepEquality;
import org.apache.jdo.tck.util.EqualityHelper;
import org.apache.jdo.tck.util.JDOCustomDateEditor;

/** This class represents information about a company. */
public class Company
    implements ICompany, Serializable, Comparable<ICompany>, Comparator<ICompany>, DeepEquality {

  private static final long serialVersionUID = 1L;

  private long companyid;
  private String name;
  private Date founded;
  private transient Set<IDepartment> departments = new HashSet<>(); // element type is Department

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

  /**
   * Initialize the <code>Company</code> instance.
   *
   * @param companyid The company id.
   * @param name The company name.
   * @param founded The date the company was founded.
   */
  public Company(long companyid, String name, Date founded) {
    this.companyid = companyid;
    this.name = name;
    this.founded = founded;
  }

  /**
   * Get the company id.
   *
   * @return The company id.
   */
  public long getCompanyid() {
    return companyid;
  }

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

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

  /**
   * Set the name of the company.
   *
   * @param name The value to use for the name of the company.
   */
  public void setName(String name) {
    this.name = name;
  }

  /**
   * Get the date that the company was founded.
   *
   * @return The date the company was founded.
   */
  public Date getFounded() {
    return founded;
  }

  /**
   * Set the date that the company was founded.
   *
   * @param founded The date to set that the company was founded.
   */
  public void setFounded(Date founded) {
    this.founded = founded;
  }

  /**
   * Get the departments contained in the company.
   *
   * @return An unmodifiable <code>Set</code> that contains all the <code>Department</code>s of the
   *     company.
   */
  public Set<IDepartment> getDepartments() {
    return Collections.unmodifiableSet(departments);
  }

  /**
   * Add a <code>Department</code> instance to the company.
   *
   * @param dept The <code>Department</code> instance to add.
   */
  public void addDepartment(Department dept) {
    departments.add(dept);
  }

  /**
   * Remove a <code>Department</code> instance from the company.
   *
   * @param dept The <code>Department</code> instance to remove.
   */
  public void removeDepartment(Department dept) {
    departments.remove(dept);
  }

  /**
   * Initialize the set of <code>Department</code>s in the company to the parameter.
   *
   * @param departments The set of <code>Department</code>s for the company.
   */
  public void setDepartments(Set<IDepartment> departments) {
    // workaround: create a new HashSet, because fostore does not
    // support LinkedHashSet
    this.departments = (departments != null) ? new HashSet<>(departments) : 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();
    departments = new HashSet<>();
  }

  /**
   * Returns a String representation of a <code>Company</code> object.
   *
   * @return a String representation of a <code>Company</code> object.
   */
  public String toString() {
    return "Company(" + 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(companyid);
    rc.append(", name ").append(name);
    rc.append(", founded ").append(JDOCustomDateEditor.getDateRepr(founded));
    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) {
    ICompany otherCompany = (ICompany) other;
    String where = "Company<" + companyid + ">";
    return helper.equals(companyid, otherCompany.getCompanyid(), where + ".companyid")
        & helper.equals(name, otherCompany.getName(), where + ".name")
        & helper.equals(founded, otherCompany.getFounded(), where + ".founded")
        & helper.deepEquals(departments, otherCompany.getDepartments(), where + ".departments");
  }

  /**
   * Compares this object with the specified Company 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 Company 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 Company object.
   */
  public int compareTo(ICompany other) {
    return compare(this, other);
  }

  /**
   * Compares its two ICompany 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 ICompany object to be compared.
   * @param o2 the second ICompany 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(ICompany o1, ICompany o2) {
    return EqualityHelper.compare(o1.getCompanyid(), o2.getCompanyid());
  }

  /**
   * 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 ICompany) {
      return compareTo((ICompany) 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) companyid;
  }

  /**
   * The class to be used as the application identifier for the <code>Company</code> class. It
   * consists of both the company name and the date that the company was founded.
   */
  public static class Oid implements Serializable, Comparable<Oid> {

    private static final long serialVersionUID = 1L;

    /**
     * This field is part of the identifier and should match in name and type with a field in the
     * <code>Company</code> class.
     */
    public long companyid;

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

    /**
     * Initialize the identifier.
     *
     * @param companyid The id of the company.
     */
    public Oid(long companyid) {
      this.companyid = companyid;
    }

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

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

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

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

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

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