/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
//     08/15/2008-1.0.1 Chris Delahunt
//       - 237545: List attribute types on OneToMany using @OrderBy does not work with attribute change tracking
package org.eclipse.persistence.testing.models.employee.domain;

import java.util.*;
import java.io.*;
import java.math.BigDecimal;
import java.sql.Time;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeEvent;
import org.eclipse.persistence.internal.helper.ConversionManager;
import org.eclipse.persistence.indirection.*;
import org.eclipse.persistence.sessions.*;
import org.eclipse.persistence.descriptors.changetracking.*;

/**
 * <p><b>Purpose</b>: Represent a employee of an organization.
 * <p><b>Description</b>: An Employee is a root object in the Employee Demo.
 * It maintains relationships to all of the other objects in the system.
 * The employee shows usage of 1-1, 1-m, m-m, aggregate and transformation mappings.
 * The employee also shows usage of value holder to implement indirection for its relationships
 * (note, it is strongly suggested to always use value holders for relationships).
 */
public class Employee implements org.eclipse.persistence.testing.models.employee.interfaces.Employee, Serializable, ChangeTracker {
    // implements ChangeTracker for testing

    /** Primary key, mapped as a direct-to-field, BigDecimal -{@literal >} NUMBER, that makes use of sequence numbers to generate the id. */
    public BigDecimal id;

    /** Direct-to-field mapping, String -{@literal >} VARCHAR. */
    public String firstName;

    /** Direct-to-field mapping, String -{@literal >} VARCHAR. */
    public String lastName;

    /** Object-type mapping, maps "Male" -{@literal >} "M", "Female" -{@literal >} "F". */
    public String gender;

    /** Primary key, mapped as a direct-to-field, BigDecimal -{@literal >} NUMBER. */
    public BigDecimal addressId;

    /** Aggregate-object mapping, stores the object in the employee's table. */
    public EmploymentPeriod period;

    /** One-to-one mapping, employee references its address through a foreign key. */
    public ValueHolderInterface address;

    /** One-to-one mapping (same class relationship), employee references its manager through a foreign key. */
    public ValueHolderInterface manager;

    /** One-to-many mapping (same class relationship), inverse relationship to manager, uses manager foreign key in the target. */
    public ValueHolderInterface managedEmployees;

    /** One-to-many mapping, employee references its collection of phone numbers using a foreign key in the phone's table. */
    public ValueHolderInterface phoneNumbers;

    /** Many-to-many mapping, employee references its projects through an intermediate join table. */
    public ValueHolderInterface projects;

    /** Direct-collection mapping, employee stores its collection of plain Strings in an intermediate table. */
    public ValueHolderInterface responsibilitiesList;

    /** Transformation mapping, a two(2) element array holding the employee's normal working hours (START_TIME &amp; END_TIME),
        this is stored into two different fields in the employee table. */
    public Time[] normalHours;

    /** Direct-to-field mapping, int -{@literal >} NUMBER, salary of the employee in dollars. */
    public int salary;

    /** One-to-many mapping, employee references its collection of children arranged by age.
     * This relationship uses transparent indirection */
    public Vector children;

    /** For performance testing, how many times primary key extracted. */
    public static int getIdCallCount = 0;
    public PropertyChangeListener listener;

    @Override
    public PropertyChangeListener _persistence_getPropertyChangeListener() {
        return listener;
    }

    @Override
    public void _persistence_setPropertyChangeListener(PropertyChangeListener listener) {
        this.listener = listener;
    }

    public void propertyChange(String propertyName, Object oldValue, Object newValue) {
        if (listener != null) {
            if (oldValue != newValue) {
                listener.propertyChange(new PropertyChangeEvent(this, propertyName, oldValue, newValue));
            }
        }
    }

    public void collectionChange(String propertyName, Object oldValue, Object newValue, int changeType, boolean isChangeApplied) {
        if (listener != null) {
            listener.propertyChange(new CollectionChangeEvent(this, propertyName, oldValue, newValue, changeType, isChangeApplied));
        }
    }

    /**
     * For fields that make use of indirection the constructor should build the value holders.
     */
    public Employee() {
        this.firstName = "";
        this.lastName = "";
        this.address = new ValueHolder();
        this.manager = new ValueHolder();
        this.managedEmployees = new ValueHolder(new Vector());
        this.projects = new ValueHolder(new Vector());
        this.responsibilitiesList = new ValueHolder(new Vector());
        this.phoneNumbers = new ValueHolder(new Vector());
        this.normalHours = new Time[2];
        Calendar startTime = Calendar.getInstance();
        startTime.set(Calendar.MILLISECOND, 0);
        startTime.set(1970, 0, 1, 9, 0, 0);
        this.normalHours[0] = new Time(startTime.getTime().getTime());
        Calendar endTime = Calendar.getInstance();
        endTime.set(Calendar.MILLISECOND, 0);
        endTime.set(1970, 0, 1, 17, 0, 0);
        this.normalHours[1] = new Time(endTime.getTime().getTime());
        this.children = new Vector();
    }

    /**
     * For bi-directional relationships, it is important to maintain both sides of the relationship when changing it.
     */
    @Override
    public void addManagedEmployee(org.eclipse.persistence.testing.models.employee.interfaces.Employee employee) {
        if(getManagedEmployees().add(employee)) {
            collectionChange("managedEmployees", managedEmployees, employee, 0, true);
            employee.setManager(this);
        }
    }

    /**
     * For bi-directional relationships, it is important to maintain both sides of the relationship when changing it.
     */
    @Override
    public void addPhoneNumber(PhoneNumber phoneNumber) {
        if(getPhoneNumbers().add(phoneNumber)) {
            collectionChange("phoneNumbers", phoneNumbers, phoneNumber, 0, true);
            phoneNumber.setOwner(this);
        }
    }

    @Override
    public void addProject(org.eclipse.persistence.testing.models.employee.interfaces.Project project) {
        if(getProjects().add(project)) {
            collectionChange("projects", projects, project, 0, true);
        }
    }

    @Override
    public void addResponsibility(String responsibility) {
        if(getResponsibilitiesList().add(responsibility)) {
            collectionChange("responsibilitiesList", responsibilitiesList, responsibility, 0, true);
        }
    }

    /**
     * Builds the normalHours Vector.
     * IMPORTANT: This method builds the value but does not set it.
     * The mapping will set it using method or direct access as defined in the descriptor.
     */
    public Time[] buildNormalHours(DataRecord row, Session session) {
        Time[] hours = new Time[2];

        /** This conversion allows for the database type not to match, i.e. may be a Timestamp or String. */
        try {
            hours[0] = session.getDatasourcePlatform().convertObject(row.get("START_TIME"), Time.class);
            hours[1] = session.getDatasourcePlatform().convertObject(row.get("END_TIME"), Time.class);
        } catch (Throwable in904) {
            // Allow performance tests to be run in 904.
            hours[0] = ConversionManager.getDefaultManager().convertObject(row.get("START_TIME"), Time.class);
            hours[1] = ConversionManager.getDefaultManager().convertObject(row.get("END_TIME"), Time.class);
        }
        return hours;
    }

    /**
     * Notice that the usage of value holders does not effect the public interface or usage of the class.
     * The get/set methods must however be changed to wrap/unwrap the value holder.
     */
    @Override
    public Address getAddress() {
        return (Address)address.getValue();
    }

    /**
     * Return the last element of the Transformation mapped normalHours.
     */
    @Override
    public Time getEndTime() {
        return getNormalHours()[1];
    }

    @Override
    public String getFirstName() {
        return firstName;
    }

    @Override
    public String getGender() {
        return gender;
    }

    /**
     * Used for performance testing.
     */
    public static int getGetIdCallCount() {
        return getIdCallCount;
    }

    /**
     * Return the persistent identifier of the receiver.
     */
    @Override
    public BigDecimal getId() {
        getIdCallCount++;
        return id;
    }

    public BigDecimal getAddressId() {
        //addressID will not exist until Address is committed
        if (addressId == null) {
            if (getAddress() != null) {
                addressId = getAddress().getId();
            }
        }
        return addressId;
    }

    public Vector getChildren(){
        return children;
    }

    public void setAddressId(BigDecimal newAddressId) {
        addressId = newAddressId;
    }

    @Override
    public String getLastName() {
        return lastName;
    }

    /**
     * Notice that the usage of value holders does not effect the public interface or usage of the class.
     * The get/set methods must however be changed to wrap/unwrap the value holder.
     */
    @Override
    public Vector getManagedEmployees() {
        return (Vector)managedEmployees.getValue();
    }

    /**
     * Notice that the usage of value holders does not effect the public interface or usage of the class.
     * The get/set methods must however be changed to wrap/unwrap the value holder.
     */
    @Override
    public org.eclipse.persistence.testing.models.employee.interfaces.Employee getManager() {
        return (Employee)manager.getValue();
    }

    @Override
    public Time[] getNormalHours() {
        return normalHours;
    }

    @Override
    public EmploymentPeriod getPeriod() {
        return period;
    }

    /**
     * Notice that the usage of value holders does not effect the public interface or usage of the class.
     * The get/set methods must however be changed to wrap/unwrap the value holder.
     */
    @Override
    public Vector getPhoneNumbers() {
        return (Vector)phoneNumbers.getValue();
    }

    /**
     * Notice that the usage of value holders does not effect the public interface or usage of the class.
     * The get/set methods must however be changed to wrap/unwrap the value holder.
     */
    @Override
    public Vector getProjects() {
        return (Vector)projects.getValue();
    }

    /**
     * Notice that the usage of value holders does not effect the public interface or usage of the class.
     * The get/set methods must however be changed to wrap/unwrap the value holder.
     */
    @Override
    public Vector getResponsibilitiesList() {
        return (Vector)responsibilitiesList.getValue();
    }

    @Override
    public int getSalary() {
        return salary;
    }

    /**
     * Return the first element of the Transformation mapped normalHours.
     */
    @Override
    public java.sql.Time getStartTime() {
        return getNormalHours()[0];
    }

    /**
     * For bi-directional relationships, it is important to maintain both sides of the relationship when changing it.
     */
    @Override
    public void removeManagedEmployee(org.eclipse.persistence.testing.models.employee.interfaces.Employee employee) {
        if(getManagedEmployees().removeElement(employee)) {
            collectionChange("managedEmployees", managedEmployees, employee, 1, true);
            employee.setManager(null);
        }
    }

    /**
     * Remove the phone number.
     * The phone number's owner must not be set to null as it is part of it primary key,
     * and you can never change the primary key of an existing object.
     * Only in independent relationships should you null out the back reference.
     */
    @Override
    public void removePhoneNumber(PhoneNumber phoneNumber) {
        if(getPhoneNumbers().removeElement(phoneNumber)) {
            collectionChange("phoneNumbers", phoneNumbers, phoneNumber, 1, true);
        }
    }

    @Override
    public void removeProject(org.eclipse.persistence.testing.models.employee.interfaces.Project project) {
        if(getProjects().removeElement(project)) {
            collectionChange("projects", projects, project, 1, true);
        }
    }

    @Override
    public void removeResponsibility(String responsibility) {
        if(getResponsibilitiesList().removeElement(responsibility)) {
            collectionChange("responsibilitiesList", responsibilitiesList, responsibility, 1, true);
        }
    }

    /**
     * Notice that the usage of value holders does not effect the public interface or usage of the class.
     * The get/set methods must however be changed to wrap/unwrap the value holder.
     */
    @Override
    public void setAddress(Address address) {
        propertyChange("address", this.address.getValue(), address);
        this.address.setValue(address);
        if (address == null) {
            this.setAddressId(null);
        } else {
            this.setAddressId(address.getId());
        }
    }

    public void setChildren(Vector children){
        this.children = children;
    }

    /**
     * Set the last element of the Transformation mapped normalHours.
     */
    @Override
    public void setEndTime(Time endTime) {
        Time[] oldHours = new Time[] { getNormalHours()[0], getNormalHours()[1] };
        getNormalHours()[1] = endTime;
        propertyChange("normalHours", oldHours, normalHours);
    }

    @Override
    public void setFemale() {
        propertyChange("gender", this.gender, "Female");
        setGender("Female");
    }

    @Override
    public void setFirstName(String firstName) {
        propertyChange("firstName", getFirstName(), firstName);
        this.firstName = firstName;
    }

    @Override
    public void setGender(String gender) {
        propertyChange("gender", this.gender, gender);
        this.gender = gender;
    }

    /**
     * For performance testing.
     */
    public static void setGetIdCallCount(int value) {
        Employee.getIdCallCount = value;
    }

    /**
     * Set the persistent identifier of the receiver.
     * Note this should never be changed.
     * Consider making the primary key set methods protected or not having them.
     * In this demo the setId is required for testing purposes.
     */
    public void setId(BigDecimal id) {
        propertyChange("id", this.id, id);
        this.id = id;
    }

    @Override
    public void setLastName(String lastName) {
        propertyChange("lastName", this.lastName, lastName);
        this.lastName = lastName;
    }

    @Override
    public void setMale() {
        propertyChange("gender", this.gender, "Male");
        setGender("Male");
    }

    /**
     * Notice that the usage of value holders does not effect the public interface or usage of the class.
     * The get/set methods must however be changed to wrap/unwrap the value holder.
     */
    @Override
    public void setManagedEmployees(Vector managedEmployees) {
        propertyChange("managedEmployees", this.managedEmployees.getValue(), managedEmployees);
        this.managedEmployees.setValue(managedEmployees);
    }

    /**
     * For bi-directional relationships, it is important to maintain both sides of the relationship when changing it.
     * Notice that the usage of value holders does not effect the public interface or usage of the class.
     * The get/set methods must however be changed to wrap/unwrap the value holder.
     */
    @Override
    public void setManager(org.eclipse.persistence.testing.models.employee.interfaces.Employee manager) {
        propertyChange("manager", this.manager.getValue(), manager);
        this.manager.setValue(manager);
    }

    @Override
    public void setNormalHours(Time[] normalHours) {
        Time[] oldHours = this.normalHours;
        this.normalHours = normalHours;
        propertyChange("normalHours", oldHours, normalHours);
    }

    @Override
    public void setPeriod(EmploymentPeriod period) {
        propertyChange("period", this.period, period);
        this.period = period;
    }

    /**
     * Notice that the usage of value holders does not effect the public interface or usage of the class.
     * The get/set methods must however be changed to wrap/unwrap the value holder.
     */
    @Override
    public void setPhoneNumbers(Vector phoneNumbers) {
        propertyChange("phoneNumbers", this.phoneNumbers.getValue(), phoneNumbers);
        this.phoneNumbers.setValue(phoneNumbers);
    }

    /**
     * Notice that the usage of value holders does not effect the public interface or usage of the class.
     * The get/set methods must however be changed to wrap/unwrap the value holder.
     */
    @Override
    public void setProjects(Vector projects) {
        propertyChange("projects", this.projects.getValue(), projects);
        this.projects.setValue(projects);
    }

    /**
     * Notice that the usage of value holders does not effect the public interface or usage of the class.
     * The get/set methods must however be changed to wrap/unwrap the value holder.
     */
    @Override
    public void setResponsibilitiesList(Vector responsibilitiesList) {
        propertyChange("responsibilitiesList", this.responsibilitiesList.getValue(), responsibilitiesList);
        this.responsibilitiesList.setValue(responsibilitiesList);
    }

    @Override
    public void setSalary(int salary) {
        propertyChange("salary", this.salary, salary);
        this.salary = salary;
    }

    /**
     * Set the first element of the Transformation mapped normalHours.
     */
    @Override
    public void setStartTime(Time startTime) {
        Time[] oldHours = new Time[] { getNormalHours()[0], getNormalHours()[1] };
        getNormalHours()[0] = startTime;
        propertyChange("normalHours", oldHours, normalHours);
    }

    /**
     * Print the first &amp; last name
     */
    public String toString() {
        StringWriter writer = new StringWriter();

        writer.write("Employee: ");
        writer.write(getFirstName());
        writer.write(" ");
        writer.write(getLastName());
        return writer.toString();
    }
}
