/*
 * 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
package org.eclipse.persistence.testing.tests.unitofwork;

import java.io.Serializable;
import java.io.StringWriter;

import java.math.BigDecimal;

import org.eclipse.persistence.descriptors.RelationalDescriptor;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.mappings.DirectToFieldMapping;
import org.eclipse.persistence.testing.tests.unitofwork.ConcurrentReadOnUpdateWithEarlyTransTest;
import org.eclipse.persistence.tools.schemaframework.TableDefinition;


/**
 * <p><b>Purpose</b>: Represents the mailing address on an Employee
 * <p><b>Description</b>: Held in a private 1:1 relationship from Employee
 * @see ConcurrentPerson
 */
public class ConcurrentAddress implements Serializable, Cloneable {
    public BigDecimal id;
    public String street;
    public String city;
    public String province;
    public String postalCode;
    public String country;

    //USED TO DETERMINE WHICH TEST IS RUNNING
    public static int RUNNING_TEST;

    //tests
    public static final int NONE = Integer.MIN_VALUE;
    public static final int LOCK_ON_CLONE_TEST = 55;
    public static final int LOCK_ON_CLONE_DEADLOCK = 56;
    public static final int READ_ON_UPDATE_EARLY_TRANS = 57;
    public static boolean isForBackup = false;

    public ConcurrentAddress() {
        this.city = "";
        this.province = "";
        this.postalCode = "";
        this.street = "";
        this.country = "";
    }

    @Override
    public Object clone() {
        ConcurrentAddress result = new ConcurrentAddress();
        result.id = this.id;
        result.city = this.city;
        result.province = this.province;
        result.postalCode = this.postalCode;
        result.street = this.street;
        result.country = this.country;
        return result;

    }

    public String getCity() {
        return city;
    }

    public String getCountry() {
        try {
            if (ConcurrentRefreshOnCloneTest.lock != null) {
                synchronized (ConcurrentRefreshOnCloneTest.lock) {
                    if (!ConcurrentRefreshOnCloneTest.waited) {
                        if (ConcurrentRefreshOnCloneTest.readerWaiting) {
                            ConcurrentRefreshOnCloneTest.lock.notifyAll();
                            Thread.yield();
                        }

                        // verify that we are not currently holding an active lock on the system.  Which would result in a deadlock
                        if (((AbstractSession)ConcurrentRefreshOnCloneTest.session).getIdentityMapAccessorInstance().getIdentityMapManager().getCacheMutex().getActiveThread() !=
                            Thread.currentThread()) {
                            ConcurrentRefreshOnCloneTest.cloneWaiting = true;
                            ConcurrentRefreshOnCloneTest.lock.wait(30000);
                            ConcurrentRefreshOnCloneTest.cloneWaiting = false;
                        } else {
                            //can't lock but let's sleep to simulate a window for refresh
                            Thread.sleep(4000);
                        }
                        ConcurrentRefreshOnCloneTest.waited = true;
                    }
                }
            }
        } catch (Exception ex) {
        }
        return country;
    }

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

    public String getPostalCode() {
        return postalCode;
    }

    public String getProvince() {
        //used in the Lock on clone test
        if ((ConcurrentAddress.RUNNING_TEST == ConcurrentAddress.LOCK_ON_CLONE_TEST) ||
            (ConcurrentAddress.RUNNING_TEST == ConcurrentAddress.LOCK_ON_CLONE_DEADLOCK)) {
            if (!isForBackup) {
                synchronized (this) {
                    isForBackup = true; //the next call to this method will be for backup
                    this.notifyAll(); // let refresh update the fields
                    try {
                        this.wait(10000); //wait for refresh to update the fields
                    } catch (InterruptedException ex) {
                    }
                }
            } else {
                isForBackup = false;
            }
        }
        return province;
    }

    public String getStreet() {
        return street;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public void setCountry(String country) {
        this.country = country;
    }

    /**
     * Set the persistent identifier of the receiver.
     */
    public void setId(BigDecimal id) {
        try {
            if (ConcurrentAddress.RUNNING_TEST == ConcurrentAddress.READ_ON_UPDATE_EARLY_TRANS) {
                if (ConcurrentReadOnUpdateWithEarlyTransTest.threadId.get().equals("Writer")) {
                    synchronized (ConcurrentReadOnUpdateWithEarlyTransTest.readAddress) {
                        ConcurrentReadOnUpdateWithEarlyTransTest.readAddress.notify(); // wake up reader.
                        ConcurrentReadOnUpdateWithEarlyTransTest.whosWaiting =
                                ConcurrentReadOnUpdateWithEarlyTransTest.WRITER;
                        ConcurrentReadOnUpdateWithEarlyTransTest.readAddress.wait(30000);
                    }
                }
            } else {
                if (ConcurrentReadOnInsertTest.readAddress != null) {
                    synchronized (ConcurrentReadOnInsertTest.readAddress) {
                        if (ConcurrentReadOnInsertTest.depth <= 0) {
                            ConcurrentReadOnInsertTest.readAddress.notifyAll();
                        } else {
                            --ConcurrentReadOnInsertTest.depth;
                        }
                    }

                    // make an extra buffer to ensure that the read has time to run
                    Thread.sleep(2000);
                }
            }
        } catch (Exception ex) {
        }
        this.id = id;
    }

    public void setPostalCode(String postalCode) {
        this.postalCode = postalCode;
    }

    public void setProvince(String province) {
        this.province = province;
    }

    public void setStreet(String street) {
        this.street = street;
    }

    /**
     * Print the address city and province.
     */
    public String toString() {
        StringWriter writer = new StringWriter();

        writer.write("Address: ");
        writer.write(this.street);
        writer.write(", ");
        writer.write(this.city);
        writer.write(", ");
        writer.write(this.province);
        writer.write(", ");
        writer.write(this.country);
        return writer.toString();
    }

    public static TableDefinition tableDefinition() {
        org.eclipse.persistence.tools.schemaframework.TableDefinition tabledefinition =
            new org.eclipse.persistence.tools.schemaframework.TableDefinition();

        // SECTION: TABLE
        tabledefinition.setName("CONCURRENT_ADDRESS");

        // SECTION: FIELD
        org.eclipse.persistence.tools.schemaframework.FieldDefinition field =
            new org.eclipse.persistence.tools.schemaframework.FieldDefinition();
        field.setName("ADDRESS_ID");
        field.setTypeName("NUMERIC");
        field.setSize(15);
        field.setShouldAllowNull(false);
        field.setIsPrimaryKey(true);
        field.setUnique(false);
        field.setIsIdentity(true);
        tabledefinition.addField(field);

        // SECTION: FIELD
        org.eclipse.persistence.tools.schemaframework.FieldDefinition field1 =
            new org.eclipse.persistence.tools.schemaframework.FieldDefinition();
        field1.setName("P_CODE");
        field1.setTypeName("VARCHAR");
        field1.setSize(20);
        field1.setShouldAllowNull(true);
        field1.setIsPrimaryKey(false);
        field1.setUnique(false);
        field1.setIsIdentity(false);
        tabledefinition.addField(field1);

        // SECTION: FIELD
        org.eclipse.persistence.tools.schemaframework.FieldDefinition field2 =
            new org.eclipse.persistence.tools.schemaframework.FieldDefinition();
        field2.setName("CITY");
        field2.setTypeName("VARCHAR");
        field2.setSize(80);
        field2.setShouldAllowNull(true);
        field2.setIsPrimaryKey(false);
        field2.setUnique(false);
        field2.setIsIdentity(false);
        tabledefinition.addField(field2);

        // SECTION: FIELD
        org.eclipse.persistence.tools.schemaframework.FieldDefinition field3 =
            new org.eclipse.persistence.tools.schemaframework.FieldDefinition();
        field3.setName("PROVINCE");
        field3.setTypeName("VARCHAR");
        field3.setSize(80);
        field3.setShouldAllowNull(true);
        field3.setIsPrimaryKey(false);
        field3.setUnique(false);
        field3.setIsIdentity(false);
        tabledefinition.addField(field3);

        // SECTION: FIELD
        org.eclipse.persistence.tools.schemaframework.FieldDefinition field4 =
            new org.eclipse.persistence.tools.schemaframework.FieldDefinition();
        field4.setName("STREET");
        field4.setTypeName("VARCHAR");
        field4.setSize(80);
        field4.setShouldAllowNull(true);
        field4.setIsPrimaryKey(false);
        field4.setUnique(false);
        field4.setIsIdentity(false);
        tabledefinition.addField(field4);

        // SECTION: FIELD
        org.eclipse.persistence.tools.schemaframework.FieldDefinition field5 =
            new org.eclipse.persistence.tools.schemaframework.FieldDefinition();
        field5.setName("COUNTRY");
        field5.setTypeName("VARCHAR");
        field5.setSize(80);
        field5.setShouldAllowNull(true);
        field5.setIsPrimaryKey(false);
        field5.setUnique(false);
        field5.setIsIdentity(false);
        tabledefinition.addField(field5);

        return tabledefinition;
    }

    public static RelationalDescriptor descriptor() {
        // NOTE: weights are set on the mapping to ensure the order in which they are
        // accessed by toplink for timing purposes for test ConcurrentRefreshOnCloneTest
        RelationalDescriptor descriptor = new RelationalDescriptor();
        descriptor.setJavaClass(ConcurrentAddress.class);
        descriptor.addTableName("CONCURRENT_ADDRESS");
        descriptor.addPrimaryKeyFieldName("CONCURRENT_ADDRESS.ADDRESS_ID");

        // RelationalDescriptor properties.
        descriptor.useFullIdentityMap();
        descriptor.setIdentityMapSize(100);
        descriptor.setSequenceNumberFieldName("ADDRESS_ID");
        descriptor.setSequenceNumberName("ADDRESS_SEQ");

        // Query manager.
        descriptor.getQueryManager().checkCacheForDoesExist();

        // Event manager.
        // Mappings.
        DirectToFieldMapping cityMapping = new DirectToFieldMapping();
        cityMapping.setAttributeName("city");
        cityMapping.setFieldName("CONCURRENT_ADDRESS.CITY");
        cityMapping.setWeight(10);
        descriptor.addMapping(cityMapping);

        DirectToFieldMapping countryMapping = new DirectToFieldMapping();
        countryMapping.setAttributeName("country");
        countryMapping.setFieldName("CONCURRENT_ADDRESS.COUNTRY");
        countryMapping.setSetMethodName("setCountry");
        countryMapping.setGetMethodName("getCountry");
        countryMapping.setWeight(9);
        descriptor.addMapping(countryMapping);

        DirectToFieldMapping idMapping = new DirectToFieldMapping();
        idMapping.setAttributeName("id");
        idMapping.setFieldName("CONCURRENT_ADDRESS.ADDRESS_ID");
        idMapping.setSetMethodName("setId");
        idMapping.setGetMethodName("getId");
        idMapping.setWeight(8);
        descriptor.addMapping(idMapping);

        DirectToFieldMapping postalCodeMapping = new DirectToFieldMapping();
        postalCodeMapping.setAttributeName("postalCode");
        postalCodeMapping.setFieldName("CONCURRENT_ADDRESS.P_CODE");
        postalCodeMapping.setWeight(7);
        descriptor.addMapping(postalCodeMapping);

        DirectToFieldMapping provinceMapping = new DirectToFieldMapping();
        provinceMapping.setAttributeName("province");
        provinceMapping.setFieldName("CONCURRENT_ADDRESS.PROVINCE");
        provinceMapping.setSetMethodName("setProvince");
        provinceMapping.setGetMethodName("getProvince");
        provinceMapping.setWeight(6);
        descriptor.addMapping(provinceMapping);

        DirectToFieldMapping streetMapping = new DirectToFieldMapping();
        streetMapping.setAttributeName("street");
        streetMapping.setFieldName("CONCURRENT_ADDRESS.STREET");
        streetMapping.setWeight(5);
        descriptor.addMapping(streetMapping);

        return descriptor;
    }
}
