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

import java.io.Serializable;
import java.util.Comparator;
import javax.jdo.annotations.PersistenceCapable;
import org.apache.jdo.tck.pc.company.IAddress;
import org.apache.jdo.tck.util.DeepEquality;
import org.apache.jdo.tck.util.EqualityHelper;

/** This class represents a postal address. */
@PersistenceCapable(embeddedOnly = "true", requiresExtent = "false")
public class FCAppAddress
    implements IAddress, Serializable, Comparable<IAddress>, Comparator<IAddress>, DeepEquality {

  private static final long serialVersionUID = 1L;

  private long addrid;
  private String street;
  private String city;
  private String state;
  private String zipcode;
  private String country;

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

  /**
   * This constructor initializes the <code>FCAppAddress</code> components.
   *
   * @param addrid The address ID.
   * @param street The street address.
   * @param city The city.
   * @param state The state.
   * @param zipcode The zip code.
   * @param country The zip country.
   */
  public FCAppAddress(
      long addrid, String street, String city, String state, String zipcode, String country) {
    this.addrid = addrid;
    this.street = street;
    this.city = city;
    this.state = state;
    this.zipcode = zipcode;
    this.country = country;
  }

  /**
   * Get the addrid associated with this object.
   *
   * @return the addrid.
   */
  public long getAddrid() {
    return addrid;
  }

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

  /**
   * Get the street component of the address.
   *
   * @return The street component of the address.
   */
  public String getStreet() {
    return street;
  }

  /**
   * Set the street component of the address.
   *
   * @param street The street component.
   */
  public void setStreet(String street) {
    this.street = street;
  }

  /**
   * Get the city.
   *
   * @return The city component of the address.
   */
  public String getCity() {
    return city;
  }

  /**
   * Set the city component of the address.
   *
   * @param city The city.
   */
  public void setCity(String city) {
    this.city = city;
  }

  /**
   * Get the state component of the address.
   *
   * @return The state.
   */
  public String getState() {
    return state;
  }

  /**
   * Set the state component of the address.
   *
   * @param state The state.
   */
  public void setState(String state) {
    this.state = state;
  }

  /**
   * Get the zipcode component of the address.
   *
   * @return The zipcode.
   */
  public String getZipcode() {
    return zipcode;
  }

  /**
   * Set the zip code component of the address.
   *
   * @param zipcode The zipcode.
   */
  public void setZipcode(String zipcode) {
    this.zipcode = zipcode;
  }

  /**
   * Get the country component of the address.
   *
   * @return The country.
   */
  public String getCountry() {
    return country;
  }

  /**
   * Set the country component of the address.
   *
   * @param country The country.
   */
  public void setCountry(String country) {
    this.country = country;
  }

  /**
   * Returns a String representation of a <code>Address</code> object.
   *
   * @return a String representation of a <code>Address</code> object.
   */
  public String toString() {
    return "Address(" + 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(addrid);
    rc.append(", street ").append(street);
    rc.append(", city ").append(city);
    rc.append(", state ").append(state);
    rc.append(", zipcode ").append(zipcode);
    rc.append(", country ").append(country);
    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) {
    FCAppAddress otherAddress = (FCAppAddress) other;
    String where = "Address<" + addrid + ">";
    return helper.equals(addrid, otherAddress.getAddrid(), where + ".addrid")
        & helper.equals(street, otherAddress.getStreet(), where + ".street")
        & helper.equals(city, otherAddress.getCity(), where + ".city")
        & helper.equals(state, otherAddress.getState(), where + ".state")
        & helper.equals(zipcode, otherAddress.getZipcode(), where + ".zipcode")
        & helper.equals(country, otherAddress.getCountry(), where + ".country");
  }

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

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

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

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

    private static final long serialVersionUID = 1L;

    /**
     * This is the identifier field for <code>Address</code> and must correspond in type and name to
     * the field in <code>Address</code>.
     */
    public long addrid;

    /** The required public, no-arg constructor. */
    public Oid() {
      addrid = 0;
    }

    /**
     * A constructor to initialize the identifier field.
     *
     * @param addrid the id of the Address.
     */
    public Oid(long addrid) {
      this.addrid = addrid;
    }

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

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

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

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

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

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