/*
 * 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
//     09/23/2008-1.1 Guy Pelletier
//       - 241651: JPA 2.0 Access Type support
//     02/25/2009-2.0 Guy Pelletier
//       - 265359: JPA 2.0 Element Collections - Metadata processing portions
//     11/06/2009-2.0 Guy Pelletier
//       - 286317: UniqueConstraint xml element is changing (plus couple other fixes, see bug)
package org.eclipse.persistence.testing.models.jpa.xml.composite.advanced.member_2;

import java.sql.Time;
import java.util.*;
import java.io.Serializable;

import jakarta.persistence.Transient;

import org.eclipse.persistence.annotations.Properties;
import org.eclipse.persistence.annotations.Property;
import org.eclipse.persistence.sessions.Record;
import org.eclipse.persistence.sessions.Session;
import org.eclipse.persistence.testing.models.jpa.xml.composite.advanced.member_1.Address;
import org.eclipse.persistence.testing.models.jpa.xml.composite.advanced.member_3.Dealer;
import org.eclipse.persistence.testing.models.jpa.xml.composite.advanced.member_3.PhoneNumber;
import org.eclipse.persistence.testing.models.jpa.xml.composite.advanced.member_3.Project;

/**
 * Employees have a one-to-many relationship with Employees through the
 * managedEmployees attribute.
 * Addresses exist in one-to-one relationships with Employees through the
 * address attribute.
 * Employees have a many-to-many relationship with Projects through the
 * projects attribute.
 *
 * Employee now has invalid annotation fields and data. This is done so that
 * we may test the XML/Annotation merging. Employee has been defined in the
 * XML, therefore, most annotations should not be processed. If they are, then
 * they will force an error, which means something is wrong with our merging.
 *
 * The invalid annotations that should not be processed have _INVALID
 * appended to some annotation field member. Others will not have this,
 * which means they should be processed (their mappings are not defined in the
 * XML)
 */
@Properties({
    // This @Property should be overridden by a property with the same name defined in xml.
    @Property(name="ToBeOverriddenByXml", value="false", valueType=Boolean.class),
    // This property should be set - there's no property with the same name defined in xml.
    @Property(name="ToBeProcessed", value="true", valueType=Boolean.class)
})
public class Employee implements Serializable {
    public enum Gender { Female, Male }
    public enum SalaryRate {JUNIOR, SENIOR, MANAGER, EXECUTIVE}

    private int salary;
    private int version;
    private Integer id;

    private String firstName;

    // Currently the property annotation on an attribute should ignored in case there's orm xml.
    @Property(name="ToBeIgnored", value="true", valueType=Boolean.class)
    private String lastName;

    private Gender gender;
    private Address address;
    private Employee manager;
    private SalaryRate payScale;
    private EmploymentPeriod period;
    private Collection<Employee> managedEmployees;

    private Collection<PhoneNumber> phoneNumbers;
    private Collection<Project> projects;
    private Collection<String> responsibilities;
    private List<Dealer> dealers;

    private Map<String, Long> creditCards;
    private static final String AMEX = "Amex";
    private static final String DINERS = "DinersClub";
    private static final String MASTERCARD = "Mastercard";
    private static final String VISA = "Visa";

    private Map<String, Long> creditLines;
    private static final String ROYAL_BANK = "RoyalBank";
    private static final String CANADIAN_IMPERIAL = "CanadianImperial";
    private static final String SCOTIABANK = "Scotiabank";
    private static final String TORONTO_DOMINION = "TorontoDominion";

    /** 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. */
    private Time[] normalHours;
    /** Transformation mapping, a two(2) element array holding the employee's overtime hours (OVERTIME_START_TIME &amp; OVERTIME_END_TIME),
    this is stored into two different fields in the employee table. */
    private Time[] overtimeHours;

    private String socialInsuranceNumber;
    //Transient value used to keep track of how many times enterSIN method was called
    private int sinChangeCounter = 0;

    public Employee () {
        phoneNumbers = new Vector<PhoneNumber>();
        projects = new Vector<Project>();
        managedEmployees = new Vector<Employee>();
        responsibilities = new Vector<String>();
        dealers = new ArrayList<Dealer>();
        creditCards = new HashMap<String, Long>();
        creditLines = new HashMap<String, Long>();
        normalHours = new Time[2];
        overtimeHours = new Time[2];
    }

    public Employee(String firstName, String lastName){
        this();
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public void addAmex(long number) {
        getCreditCards().put(AMEX, number);
    }

    public void addCanadianImperialCreditLine(long number) {
        getCreditLines().put(CANADIAN_IMPERIAL, number);
    }

    public void addDealer(Dealer dealer) {
        dealers.add(dealer);
    }

    public void addDinersClub(long number) {
        getCreditCards().put(DINERS, number);
    }

    public void addManagedEmployee(Employee emp) {
        getManagedEmployees().add(emp);
        emp.setManager(this);
    }

    public void addMastercard(long number) {
        getCreditCards().put(MASTERCARD, number);
    }

    public void addPhoneNumber(PhoneNumber phone) {
        phone.setOwner(this);
        getPhoneNumbers().add(phone);
    }

    public void addProject(Project theProject) {
        getProjects().add(theProject);
    }

    public void addResponsibility(String responsibility) {
        getResponsibilities().add(responsibility);
    }

    public void addRoyalBankCreditLine(long number) {
        getCreditLines().put(ROYAL_BANK, number);
    }

    public void addScotiabankCreditLine(long number) {
        getCreditLines().put(SCOTIABANK, number);
    }

    public void addTorontoDominionCreditLine(long number) {
        getCreditLines().put(TORONTO_DOMINION, number);
    }

    public void addVisa(long number) {
        getCreditCards().put(VISA, number);
    }

    /**
     * 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(Record 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. */
        hours[0] = session.getDatasourcePlatform().convertObject(row.get("START_TIME"), Time.class);
        hours[1] = session.getDatasourcePlatform().convertObject(row.get("END_TIME"), Time.class);
        return hours;
    }

    public String displayString() {
        StringBuffer sbuff = new StringBuffer();
        sbuff.append("Employee ").append(getId()).append(": ").append(getLastName()).append(", ").append(getFirstName()).append(getSalary());

        return sbuff.toString();
    }

    //used for test user defined getter and setter methods
    public void enterSIN(String socialInsuranceNumber){
        this.sinChangeCounter++;
        this.socialInsuranceNumber=socialInsuranceNumber;
    }

    // Static method should be ignored
    static public void getAbsolutelyNothing() {}

    public Address getAddress() {
        return address;
    }

    // Get methods with no corresponding set method, should be ignored.
    // logs a warning though.
    public String getAnEmptyString() {
        return "";
    }

    // EclipseLink feature, mark it transient so JPA ORM doesn't process it.
    @Transient
    public Map<String, Long> getCreditCards() {
        return creditCards;
    }

    // EclipseLink feature, mark it transient so JPA ORM doesn't process it.
    @Transient
    public Map<String, Long> getCreditLines() {
        return creditLines;
    }

    public List<Dealer> getDealers() {
        return dealers;
    }

    /**
     * Return the last element of the Transformation mapped overtimeHours.
     */
    @Transient
    public Time getEndOvertime() {
        return getOvertimeHours()[1];
    }

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

    public String getFirstName() {
        return firstName;
    }

    public Gender getGender() {
        return gender;
    }

    public Integer getId() {
        return id;
    }

    public String getLastName() {
        return lastName;
    }

    public Collection<Employee> getManagedEmployees() {
        return managedEmployees;
    }

    public Employee getManager() {
        return manager;
    }

    @Transient
    protected Time[] getNormalHours() {
        return normalHours;
    }

    @Transient
    protected Time[] getOvertimeHours() {
        return overtimeHours;
    }

    public SalaryRate getPayScale() {
        return payScale;
    }

    public EmploymentPeriod getPeriod() {
        return period;
    }

    public Collection<PhoneNumber> getPhoneNumbers() {
        return phoneNumbers;
    }

    public Collection<Project> getProjects() {
        return projects;
    }

    public Collection<String> getResponsibilities() {
        return responsibilities;
    }

    public int getSalary() {
        return salary;
    }

    /**
     * Return the first element of the Transformation mapped overtimeHours.
     */
    @Transient
    public java.sql.Time getStartOvertime() {
        return getOvertimeHours()[0];
    }

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

    public int getVersion() {
        return version;
    }

    // Get methods with parameters should be ignored
    public String getYourStringBack(String str) {
        return str;
    }


    public boolean hasAmex(long number) {
        return hasCard(creditCards.get(AMEX), number);
    }

    public boolean hasCanadianImperialCreditLine(long number) {
        return hasCreditLine(creditLines.get(CANADIAN_IMPERIAL), number);
    }

    private boolean hasCard(Long cardNumber, long number) {
        if (cardNumber == null) {
            return false;
        } else {
            return cardNumber == number;
        }
    }

    private boolean hasCreditLine(Long creditLineNumber, long number) {
        if (creditLineNumber == null) {
            return false;
        } else {
            return creditLineNumber == number;
        }
    }

    public boolean hasDinersClub(long number) {
        return hasCard(creditCards.get(DINERS), number);
    }

    public boolean hasMastercard(long number) {
        return hasCard(creditCards.get(MASTERCARD), number);
    }

    public boolean hasRoyalBankCreditLine(long number) {
        return hasCreditLine(creditLines.get(ROYAL_BANK), number);
    }

    public boolean hasScotiabankCreditLine(long number) {
        return hasCreditLine(creditLines.get(SCOTIABANK), number);
    }

    public boolean hasTorontoDominionCreditLine(long number) {
        return hasCreditLine(creditLines.get(TORONTO_DOMINION), number);
    }

    public boolean hasVisa(long number) {
        return hasCard(creditCards.get(VISA), number);
    }

    public boolean isFemale() {
        return gender.equals(Gender.Female);
    }

    public boolean isMale() {
        return gender.equals(Gender.Male);
    }

    public void removeDealer(Dealer dealer) {
        dealers.remove(dealer);
    }

    public void removeManagedEmployee(Employee emp) {
        getManagedEmployees().remove(emp);
    }

    public void removePhoneNumber(PhoneNumber phone) {
        // Note that getPhoneNumbers() will not have a phone number identical to
        // "phone", (because it's serialized) and this will take advantage of
        // equals() in PhoneNumber to remove properly
        getPhoneNumbers().remove(phone);
    }

    public void removeProject(Project theProject) {
        getProjects().remove(theProject);
    }

    public void removeResponsibility(String responsibility) {
        getResponsibilities().remove(responsibility);
    }

    //used for test user defined getter and setter methods
    public String returnSIN(){
        return socialInsuranceNumber;
    }

    //used to keep track of how many times enterSIN was called
    public int returnSinChangeCounter(){
        return this.sinChangeCounter;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    protected void setCreditCards(Map<String, Long> creditCards) {
        this.creditCards = creditCards;
    }

    protected void setCreditLines(Map<String, Long> creditLines) {
        this.creditLines = creditLines;
    }

    public void setDealers(List<Dealer> dealers) {
        this.dealers = dealers;
    }

    /**
     * Set the last element of the Transformation mapped overtimeHours.
     * In order to have change tracking, the transformation mapping is not mutable,
     * therefore the whole new array should be created in case either element is changed.
     */
    public void setEndOvertime(Time endOvertime) {
        Time[] newOvertimeHours = new Time[] {getStartOvertime(), endOvertime};
        setOvertimeHours(newOvertimeHours);
    }

    /**
     * Set the last element of the Transformation mapped normalHours.
     * In order to have change tracking, the transformation mapping is not mutable,
     * therefore the whole new array should be created in case either element is changed.
     */
    public void setEndTime(Time endTime) {
        Time[] newNormalHours = new Time[] {getStartTime(), endTime};
        setNormalHours(newNormalHours);
    }

    public void setFemale() {
        this.gender = Gender.Female;
    }

    // This mapping has been marked as having field access. I've therefore
    // renamed the set method to test that the processing does not process
    // the mapping as PROPERTY and look for an equivalent set method for the
    // get. Otherwise a processing error will occur.
    public void setGivenName(String name) {
        this.firstName = name;
    }

    public void setGender(Gender gender) {
        this.gender = gender;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    // This mapping has been marked as having field access. I've therefore
    // renamed the set method to test that the processing does not process
    // the mapping as PROPERTY and look for an equivalent set method for the
    // get. Otherwise a processing error will occur.
    public void setFamilyName(String name) {
        this.lastName = name;
    }

    public void setMale() {
        this.gender = Gender.Male;
    }

    public void setManagedEmployees(Collection<Employee> managedEmployees) {
        this.managedEmployees = managedEmployees;
    }

    public void setManager(Employee manager) {
        this.manager = manager;
    }

    public void setNormalHours(Time[] normalHours) {
        this.normalHours = normalHours;
    }

    public void setOvertimeHours(Time[] overtimeHours) {
        this.overtimeHours = overtimeHours;
    }

    public void setPayScale(SalaryRate payScale) {
        this.payScale = payScale;
    }

    public void setPeriod(EmploymentPeriod period) {
        this.period = period;
    }

    public void setPhoneNumbers(Collection<PhoneNumber> phoneNumbers) {
        this.phoneNumbers = phoneNumbers;
    }

    public void setProjects(Collection<Project> projects) {
        this.projects = projects;
    }

    public void setResponsibilities(Collection<String> responsibilities) {
        this.responsibilities = responsibilities;
    }

    public void setSalary(int salary) {
        this.salary = salary;
    }

    /**
     * Set the first element of the Transformation mapped overtimeHours.
     * In order to have change tracking, the transformation mapping is not mutable,
     * therefore the whole new array should be created in case either element is changed.
     */
    public void setStartOvertime(Time startOvertime) {
        Time[] newOvertimeHours = new Time[] {startOvertime, getEndOvertime()};
        setOvertimeHours(newOvertimeHours);
    }

    /**
     * Set the first element of the Transformation mapped normalHours.
     * In order to have change tracking, the transformation mapping is not mutable,
     * therefore the whole new array should be created in case either element is changed.
     */
    public void setStartTime(Time startTime) {
        Time[] newNormalHours = new Time[] {startTime, getEndTime()};
        setNormalHours(newNormalHours);
    }

    protected void setVersion(int version) {
        this.version = version;
    }

    public String toString() {
        return "Employee: " + getId();
    }
}
