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

import java.util.*;
import java.io.*;
import org.eclipse.persistence.indirection.*;
import org.eclipse.persistence.sessions.*;
import org.eclipse.persistence.testing.tests.transparentindirection.TestHashtable;

/**
 * Simple order object. Just a test fixture.
 * @author: Big Country
 */
public abstract class AbstractOrder implements Serializable {
    public int id;
    public String customerName;
    public Stack contacts2;// test NoIndirectionPolicy for Vectors
    public TestHashtable salesReps2;// test NoIndirectionPolicy for Hashtables
    public ValueHolderInterface total;// test TransformationMapping
    public int total2;

    /**
     * TopLink constructor
     */
    public AbstractOrder() {
        super();
        this.initialize();
    }

    /**
     * Constructor
     */
    public AbstractOrder(String customerName) {
        this();
        this.initialize(customerName);
    }

    public abstract void addContact(String contact);

    public void addContact2(String contact) {
        contacts2.addElement(contact);
    }

    public abstract void addLine(AbstractOrderLine line);

    public abstract void addSalesRep(AbstractSalesRep salesRep);

    public void addSalesRep2(AbstractSalesRep salesRep) {
        salesReps2.put(salesRep.getKey(), salesRep);
        salesRep.addOrder2(this);
    }

    public abstract boolean containsContact(String contactName);

    public boolean containsContact2(String contactName) {
        return contacts2.contains(contactName);
    }

    public abstract boolean containsLine(AbstractOrderLine line);

    public abstract boolean containsSalesRep(AbstractSalesRep salesRep);

    public boolean containsSalesRep2(AbstractSalesRep salesRep) {
        return salesReps2.contains(salesRep);
    }

    public Vector getAttributeVector(Enumeration stream) {
        Vector result = new Vector();
        while (stream.hasMoreElements()) {
            result.addElement(stream.nextElement());
        }
        return result;
    }

    public abstract Object getContactContainer();

    public Object getContactContainer2() {
        return contacts2;
    }

    public abstract Enumeration getContactStream();

    public Enumeration getContactStream2() {
        return contacts2.elements();
    }

    public Vector getContactVector() {
        return getAttributeVector(this.getContactStream());
    }

    public Vector getContactVector2() {
        return getAttributeVector(this.getContactStream2());
    }

    public abstract Object getLineContainer();

    public abstract void clearLines();

    public abstract Enumeration getLineStream();

    public Vector getLineVector() {
        return getAttributeVector(this.getLineStream());
    }

    public abstract int getNumberOfContacts();

    public int getNumberOfContacts2() {
        return contacts2.size();
    }

    public abstract int getNumberOfLines();

    public abstract int getNumberOfSalesReps();

    public int getNumberOfSalesReps2() {
        return salesReps2.size();
    }

    public abstract Object getSalesRepContainer();

    public Object getSalesRepContainer2() {
        return salesReps2;
    }

    public abstract Enumeration getSalesRepStream();

    public Enumeration getSalesRepStream2() {
        return salesReps2.elements();
    }

    public Vector getSalesRepVector() {
        return getAttributeVector(this.getSalesRepStream());
    }

    public Vector getSalesRepVector2() {
        return getAttributeVector(this.getSalesRepStream2());
    }

    public int getTotal() {
        return ((Integer)total.getValue()).intValue();
    }

    public int getTotalFromRow(org.eclipse.persistence.sessions.Record row, Session session) {
        int tens = ((Number)row.get("TOTT")).intValue();
        int ones = ((Number)row.get("TOTO")).intValue();
        return (tens * 10) + ones;
    }

    public int getTotalFromRow2(org.eclipse.persistence.sessions.Record row, Session session) {
        int tens = ((Number)row.get("TOTT2")).intValue();
        int ones = ((Number)row.get("TOTO2")).intValue();
        return (tens * 10) + ones;
    }

    public int getTotalOnes() {
        return this.getTotal() - ((this.getTotal() / 10) * 10);
    }

    public int getTotalOnes2() {
        return total2 - ((total2 / 10) * 10);
    }

    public int getTotalTens() {
        return this.getTotal() / 10;
    }

    public int getTotalTens2() {
        return total2 / 10;
    }

    /**
     * initialize the instance
     */
    protected void initialize() {
        this.contacts2 = new Stack();
        this.salesReps2 = new TestHashtable();
        this.total = new ValueHolder(Integer.valueOf(1));
        this.total2 = 0;
    }

    /**
     * initialize the instance
     */
    protected void initialize(String customerName) {
        this.customerName = customerName;
    }

    public abstract void removeContact(String contact);

    public void removeContact2(String contact) {
        contacts2.removeElement(contact);
    }

    public abstract void removeLine(AbstractOrderLine line);

    public abstract void removeSalesRep(AbstractSalesRep salesRep);

    public void removeSalesRep2(AbstractSalesRep salesRep) {
        salesReps2.remove(salesRep.getKey());
        salesRep.removeOrder2(this);
    }

    public void setTotal(int total) {
        this.total.setValue(Integer.valueOf(total));
    }

    public String toString() {
        StringBuffer buffer = new StringBuffer(1000);
        buffer.append("Order(");
        buffer.append(id);
        buffer.append(": ");
        buffer.append(customerName);
        buffer.append(")");
        Object container = this.getLineContainer();
        if (container == null) {
            return buffer.toString();
        }

        buffer.append(System.getProperty("line.separator"));
        if ((container instanceof IndirectContainer) && (!((IndirectContainer)container).isInstantiated())) {
            buffer.append("\t");
            buffer.append("uninstantiated order lines...");
        } else {
            for (Enumeration stream = getLineStream(); stream.hasMoreElements();) {
                buffer.append("\t");
                buffer.append(stream.nextElement());
                buffer.append(System.getProperty("line.separator"));
            }
        }
        return buffer.toString();
    }
}
