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

import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import javax.jdo.annotations.PersistenceCapable;
import org.apache.jdo.tck.util.EqualityHelper;
import org.apache.jdo.tck.util.JDOCustomDateEditor;

/** This class represents an employee. */
@PersistenceCapable
public abstract class Employee extends Person implements IEmployee {

  private static final long serialVersionUID = 1L;

  private Date hiredate;
  private double weeklyhours;
  private DentalInsurance dentalInsurance;
  private MedicalInsurance medicalInsurance;
  private Department department;
  private Department fundingDept;
  private Employee manager;
  private Employee mentor;
  private Employee protege;
  private Employee hradvisor;
  private transient Set<IProject> reviewedProjects = new HashSet<>(); // element-type is Project
  private transient Set<IProject> projects = new HashSet<>(); // element-type is Project
  private transient Set<IEmployee> team = new HashSet<>(); // element-type is Employee
  private transient Set<IEmployee> hradvisees = new HashSet<>(); // element-type is Employee

  /** This is the JDO-required no-args constructor */
  protected Employee() {}

  /**
   * Construct an <code>Employee</code> instance.
   *
   * @param personid The identifier for the person.
   * @param firstname The first name of the employee.
   * @param lastname The last name of the employee.
   * @param middlename The middle name of the employee.
   * @param birthdate The birth date of the employee.
   * @param hiredate The date that the employee was hired.
   */
  public Employee(
      long personid,
      String firstname,
      String lastname,
      String middlename,
      Date birthdate,
      Date hiredate) {
    super(personid, firstname, lastname, middlename, birthdate);
    this.hiredate = hiredate;
  }

  /**
   * Construct an <code>Employee</code> instance.
   *
   * @param personid The identifier for the person.
   * @param firstname The first name of the employee.
   * @param lastname The last name of the employee.
   * @param middlename The middle name of the employee.
   * @param birthdate The birth date of the employee.
   * @param address The address of the employee.
   * @param hiredate The date that the employee was hired.
   */
  public Employee(
      long personid,
      String firstname,
      String lastname,
      String middlename,
      Date birthdate,
      IAddress address,
      Date hiredate) {
    super(personid, firstname, lastname, middlename, birthdate, address);
    this.hiredate = hiredate;
  }

  /**
   * Get the date that the employee was hired.
   *
   * @return The date the employee was hired.
   */
  public Date getHiredate() {
    return hiredate;
  }

  /**
   * Set the date that the employee was hired.
   *
   * @param hiredate The date the employee was hired.
   */
  public void setHiredate(Date hiredate) {
    this.hiredate = hiredate;
  }

  /**
   * Get the weekly hours of the employee.
   *
   * @return The number of hours per week that the employee works.
   */
  public double getWeeklyhours() {
    return weeklyhours;
  }

  /**
   * Set the number of hours per week that the employee works.
   *
   * @param weeklyhours The number of hours per week that the employee works.
   */
  public void setWeeklyhours(double weeklyhours) {
    this.weeklyhours = weeklyhours;
  }

  /**
   * Get the reviewed projects.
   *
   * @return The reviewed projects as an unmodifiable set.
   */
  public Set<IProject> getReviewedProjects() {
    return Collections.unmodifiableSet(reviewedProjects);
  }

  /**
   * Add a reviewed project.
   *
   * @param project A reviewed project.
   */
  public void addReviewedProjects(IProject project) {
    reviewedProjects.add(project);
  }

  /**
   * Remove a reviewed project.
   *
   * @param project A reviewed project.
   */
  public void removeReviewedProject(IProject project) {
    reviewedProjects.remove(project);
  }

  /**
   * Set the reviewed projects for the employee.
   *
   * @param reviewedProjects The set of reviewed projects.
   */
  public void setReviewedProjects(Set<IProject> reviewedProjects) {
    // workaround: create a new HashSet, because fostore does not
    // support LinkedHashSet
    this.reviewedProjects = (reviewedProjects != null) ? new HashSet<>(reviewedProjects) : null;
  }

  /**
   * Get the employee's projects.
   *
   * @return The employee's projects are returned as an unmodifiable set.
   */
  public Set<IProject> getProjects() {
    return Collections.unmodifiableSet(projects);
  }

  /**
   * Add a project for the employee.
   *
   * @param project The project.
   */
  public void addProject(IProject project) {
    projects.add(project);
  }

  /**
   * Remove a project from an employee's set of projects.
   *
   * @param project The project.
   */
  public void removeProject(IProject project) {
    projects.remove(project);
  }

  /**
   * Set the projects for the employee.
   *
   * @param projects The set of projects of the employee.
   */
  public void setProjects(Set<IProject> projects) {
    // workaround: create a new HashSet, because fostore does not
    // support LinkedHashSet
    this.projects = (projects != null) ? new HashSet<>(projects) : null;
  }

  /**
   * Get the dental insurance of the employee.
   *
   * @return The employee's dental insurance.
   */
  public IDentalInsurance getDentalInsurance() {
    return dentalInsurance;
  }

  /**
   * Set the dental insurance object for the employee.
   *
   * @param dentalInsurance The dental insurance object to associate with the employee.
   */
  public void setDentalInsurance(IDentalInsurance dentalInsurance) {
    this.dentalInsurance = (DentalInsurance) dentalInsurance;
  }
  /**
   * Get the medical insurance of the employee.
   *
   * @return The employee's medical insurance.
   */
  public IMedicalInsurance getMedicalInsurance() {
    return medicalInsurance;
  }

  /**
   * Set the medical insurance object for the employee.
   *
   * @param medicalInsurance The medical insurance object to associate with the employee.
   */
  public void setMedicalInsurance(IMedicalInsurance medicalInsurance) {
    this.medicalInsurance = (MedicalInsurance) medicalInsurance;
  }

  /**
   * Get the employee's department.
   *
   * @return The department associated with the employee.
   */
  public IDepartment getDepartment() {
    return department;
  }

  /**
   * Set the employee's department.
   *
   * @param department The department.
   */
  public void setDepartment(IDepartment department) {
    this.department = (Department) department;
  }

  /**
   * Get the employee's funding department.
   *
   * @return The funding department associated with the employee.
   */
  public IDepartment getFundingDept() {
    return fundingDept;
  }

  /**
   * Set the employee's funding department.
   *
   * @param department The funding department.
   */
  public void setFundingDept(IDepartment department) {
    this.fundingDept = (Department) department;
  }

  /**
   * Get the employee's manager.
   *
   * @return The employee's manager.
   */
  public IEmployee getManager() {
    return manager;
  }

  /**
   * Set the employee's manager.
   *
   * @param manager The employee's manager.
   */
  public void setManager(IEmployee manager) {
    this.manager = (Employee) manager;
  }

  /**
   * Get the employee's team.
   *
   * @return The set of <code>Employee</code>s on this employee's team, returned as an unmodifiable
   *     set.
   */
  public Set<IEmployee> getTeam() {
    return Collections.unmodifiableSet(team);
  }

  /**
   * Add an <code>Employee</code> to this employee's team. This method sets both sides of the
   * relationship, modifying this employees team to include parameter emp and modifying emp to set
   * its manager attribute to this object.
   *
   * @param emp The <code>Employee</code> to add to the team.
   */
  public void addToTeam(Employee emp) {
    team.add(emp);
    emp.manager = this;
  }

  /**
   * Remove an <code>Employee</code> from this employee's team. This method will also set the <code>
   * emp</code> manager to null.
   *
   * @param emp The <code>Employee</code> to remove from the team.
   */
  public void removeFromTeam(Employee emp) {
    team.remove(emp);
    emp.manager = null;
  }

  /**
   * Set the employee's team.
   *
   * @param team The set of <code>Employee</code>s.
   */
  public void setTeam(Set<IEmployee> team) {
    // workaround: create a new HashSet, because fostore does not
    // support LinkedHashSet
    this.team = (team != null) ? new HashSet<>(team) : null;
  }

  /**
   * Set the mentor for this employee.
   *
   * @param mentor The mentor for this employee.
   */
  public void setMentor(IEmployee mentor) {
    this.mentor = (Employee) mentor;
  }

  /**
   * Get the mentor for this employee.
   *
   * @return The mentor.
   */
  public IEmployee getMentor() {
    return mentor;
  }

  /**
   * Set the protege for this employee.
   *
   * @param protege The protege for this employee.
   */
  public void setProtege(IEmployee protege) {
    this.protege = (Employee) protege;
  }

  /**
   * Get the protege of this employee.
   *
   * @return The protege of this employee.
   */
  public IEmployee getProtege() {
    return protege;
  }

  /**
   * Set the HR advisor for this employee.
   *
   * @param hradvisor The hradvisor for this employee.
   */
  public void setHradvisor(IEmployee hradvisor) {
    this.hradvisor = (Employee) hradvisor;
  }

  /**
   * Get the HR advisor for the employee.
   *
   * @return The HR advisor.
   */
  public IEmployee getHradvisor() {
    return hradvisor;
  }

  /**
   * Get the HR advisees of this HR advisor.
   *
   * @return An unmodifiable <code>Set</code> containing the <code>Employee</code>s that are HR
   *     advisees of this employee.
   */
  public Set<IEmployee> getHradvisees() {
    return Collections.unmodifiableSet(hradvisees);
  }

  /**
   * Add an <code>Employee</code> as an advisee of this HR advisor. This method also sets the <code>
   * emp</code> hradvisor to reference this object. In other words, both sides of the relationship
   * are set.
   *
   * @param emp The employee to add as an advisee.
   */
  public void addAdvisee(Employee emp) {
    hradvisees.add(emp);
    emp.hradvisor = this;
  }

  /**
   * Remove an <code>Employee</code> as an advisee of this HR advisor. This method also sets the
   * <code>emp</code> hradvisor to null. In other words, both sides of the relationship are set.
   *
   * @param emp The employee to add as an HR advisee.
   */
  public void removeAdvisee(Employee emp) {
    hradvisees.remove(emp);
    emp.hradvisor = null;
  }

  /**
   * Set the HR advisees of this HR advisor.
   *
   * @param hradvisees The <code>Employee</code>s that are HR advisees of this employee.
   */
  public void setHradvisees(Set<IEmployee> hradvisees) {
    // workaround: create a new HashSet, because fostore does not
    // support LinkedHashSet
    this.hradvisees = (hradvisees != null) ? new HashSet<>(hradvisees) : 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();
    reviewedProjects = new HashSet<>();
    projects = new HashSet<>();
    team = new HashSet<>();
    hradvisees = new HashSet<>();
  }

  /**
   * Return a String representation of a <code>Employee</code> object.
   *
   * @return a String representation of a <code>Employee</code> object.
   */
  @Override
  public String toString() {
    return "Employee(" + getFieldRepr() + ")";
  }

  /**
   * Returns a String representation of the non-relationship fields.
   *
   * @return a String representation of the non-relationship fields.
   */
  @Override
  protected String getFieldRepr() {
    StringBuilder rc = new StringBuilder();
    rc.append(super.getFieldRepr());
    rc.append(", hired ").append(JDOCustomDateEditor.getDateRepr(hiredate));
    rc.append(", weeklyhours ").append(weeklyhours);
    return rc.toString();
  }

  /**
   * Returns <code>true</code> if all the fields of this instance are deep equal to the
   * corresponding fields of the specified Employee.
   *
   * @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.
   */
  @Override
  public boolean deepCompareFields(Object other, EqualityHelper helper) {
    IEmployee otherEmp = (IEmployee) other;
    String where = "Employee<" + getPersonid() + ">";
    return super.deepCompareFields(otherEmp, helper)
        & helper.equals(hiredate, otherEmp.getHiredate(), where + ".hiredate")
        & helper.closeEnough(weeklyhours, otherEmp.getWeeklyhours(), where + ".weeklyhours")
        & helper.deepEquals(
            dentalInsurance, otherEmp.getDentalInsurance(), where + ".dentalInsurance")
        & helper.deepEquals(
            medicalInsurance, otherEmp.getMedicalInsurance(), where + ".medicalInsurance")
        & helper.deepEquals(department, otherEmp.getDepartment(), where + ".department")
        & helper.deepEquals(fundingDept, otherEmp.getFundingDept(), where + ".fundingDept")
        & helper.deepEquals(manager, otherEmp.getManager(), where + ".manager")
        & helper.deepEquals(mentor, otherEmp.getMentor(), where + ".mentor")
        & helper.deepEquals(protege, otherEmp.getProtege(), where + ".protege")
        & helper.deepEquals(hradvisor, otherEmp.getHradvisor(), where + ".hradvisor")
        & helper.deepEquals(
            reviewedProjects, otherEmp.getReviewedProjects(), where + ".reviewedProjects")
        & helper.deepEquals(projects, otherEmp.getProjects(), where + ".projects")
        & helper.deepEquals(team, otherEmp.getTeam(), where + ".team")
        & helper.deepEquals(hradvisees, otherEmp.getHradvisees(), where + ".hradvisees");
  }
}
