/*
 * 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
 *
 *     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
=======
 * 
 *     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.companyAnnotatedPC;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.util.Comparator;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import javax.jdo.annotations.Column;
import javax.jdo.annotations.Discriminator;
import javax.jdo.annotations.DiscriminatorStrategy;
import javax.jdo.annotations.Element;
import javax.jdo.annotations.Embedded;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.Inheritance;
import javax.jdo.annotations.InheritanceStrategy;
import javax.jdo.annotations.NotPersistent;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.PersistenceModifier;
import javax.jdo.annotations.Persistent;
import org.apache.jdo.tck.pc.company.IAddress;
import org.apache.jdo.tck.pc.company.ICompany;
import org.apache.jdo.tck.pc.company.IDepartment;
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. */
@PersistenceCapable(identityType = IdentityType.APPLICATION, table = "companies")
@Inheritance(strategy = InheritanceStrategy.NEW_TABLE)
@Discriminator(strategy = DiscriminatorStrategy.CLASS_NAME, column = "DISCRIMINATOR")
public class PCAppCompany
    implements ICompany, Serializable, Comparable<ICompany>, Comparator<ICompany>, DeepEquality {

  private static final long serialVersionUID = 1L;

  @NotPersistent() private long _companyid;
  @NotPersistent() private String _name;
  @NotPersistent() private Date _founded;
  @NotPersistent() private PCAppAddress _address;
  @NotPersistent() private transient Set<IDepartment> _departments = new HashSet<>();

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

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

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

  /**
   * Get the company id.
   *
   * @return The company id.
   */
  @Persistent(primaryKey = "true")
  @Column(name = "ID")
  public long getCompanyid() {
    return _companyid;
  }

  /**
   * Set the id associated with this object.
   *
   * @param id the id.
   */
  public void setCompanyid(long id) {
    this._companyid = id;
  }

  /**
   * Get the name of the company.
   *
   * @return The name of the company.
   */
  @Column(name = "NAME", jdbcType = "VARCHAR")
  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.
   */
  @Column(name = "FOUNDEDDATE")
  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 address of the company.
   *
   * @return The primary address of the company.
   */
  @Persistent(
      persistenceModifier = PersistenceModifier.PERSISTENT,
      types = org.apache.jdo.tck.pc.companyAnnotatedPC.PCAppAddress.class)
  @Embedded(
      nullIndicatorColumn = "COUNTRY",
      members = {
        @Persistent(name = "addrid", columns = @Column(name = "ADDRID")),
        @Persistent(name = "street", columns = @Column(name = "STREET")),
        @Persistent(name = "city", columns = @Column(name = "CITY")),
        @Persistent(name = "state", columns = @Column(name = "STATE")),
        @Persistent(name = "zipcode", columns = @Column(name = "ZIPCODE")),
        @Persistent(name = "country", columns = @Column(name = "COUNTRY"))
      })
  public IAddress getAddress() {
    return _address;
  }

  /**
   * Set the primary address for the company.
   *
   * @param address The address to set for the company.
   */
  public void setAddress(IAddress address) {
    this._address = (PCAppAddress) address;
  }

  /**
   * Get the departments contained in the company.
   *
   * @return All the <code>PCAppDepartment</code>s of the company.
   */
  @Persistent(persistenceModifier = PersistenceModifier.PERSISTENT, mappedBy = "company")
  @Element(types = org.apache.jdo.tck.pc.companyAnnotatedPC.PCAppDepartment.class)
  public Set<IDepartment> getDepartments() {
    return _departments;
  }

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

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

  /**
   * Initialize the set of <code>PCAppDepartment</code>s in the company to the parameter.
   *
   * @param departments The set of <code>PCAppDepartment</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) {
    PCAppCompany otherCompany = (PCAppCompany) 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(_address, otherCompany.getAddress(), where + ".address")
        & 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 PCAppCompany) {
      return compareTo((PCAppCompany) 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);
    }
  }
}
