/*
 * 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 FCDSAddress
    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 FCDSAddress() {}

  /**
   * This constructor initializes the <code>FCDSAddress</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 FCDSAddress(
      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) {
    FCDSAddress otherAddress = (FCDSAddress) 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 FCDSAddress 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 FCDSAddress object to be compared.
   * @param o2 the second FFCDSAddressobject 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 FCDSAddress) {
      return compareTo((FCDSAddress) 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);
    }
  }
}
