/*
 * 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:
//     Denise Smith - December 15, 2009
package org.eclipse.persistence.testing.oxm.mappings.binarydatacollection;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.Vector;
import jakarta.activation.DataHandler;

import org.eclipse.persistence.internal.helper.ConversionManager;
import org.eclipse.persistence.internal.oxm.conversion.Base64;

public class EmployeeWithByteArrayObject {
    public static final int DEFAULT_ID = 123;
    private int id;
    private Vector photos;

    public EmployeeWithByteArrayObject() {
        super();
    }

    public EmployeeWithByteArrayObject(int id) {
        super();
        this.id = id;
    }

    public EmployeeWithByteArrayObject(int id, Vector photos) {
        super();
        this.id = id;
        this.photos = photos;
    }

    public static Employee example1() {
        Vector photos = new Vector();
        byte[] bytes = MyAttachmentUnmarshaller.PHOTO_BASE64.getBytes();
        Byte[] objectBytes = new Byte[bytes.length];
        for (int index = 0; index < bytes.length; index++) {
            objectBytes[index] = bytes[index];
        }
        photos.addElement(objectBytes);
        photos.addElement(objectBytes);
        photos.addElement(objectBytes);
        return new Employee(DEFAULT_ID, photos);
    }

    public int getID() {
        return id;
    }

    public void setID(int newId) {
        id = newId;
    }

    public Vector getPhotos() {
        return photos;
    }

    public void setPhotos(Vector vectorOfPhotos) {
        photos = vectorOfPhotos;
    }

    public String toString() {
        String returnString = "Employee: " + this.getID() + " ";
        if (getPhotos() != null) {
            returnString += "Photos: ";
            for (int i = 0; i < getPhotos().size(); i++) {
                Object next = getPhotos().elementAt(i);
                if (next != null) {
                    returnString += next + " ";
                    if(next instanceof Byte[]) {
                        returnString = "\n" + "-->" + new String(Base64.base64Encode(((byte[])ConversionManager.getDefaultManager().convertObject(next, byte[].class))));
                    }
                } else {
                    returnString += ("null_item" + " ");
                }
            }
        }

        return returnString;
    }

    public boolean equals(Object object) {
        if (!(object instanceof EmployeeWithByteArrayObject)) {
            return false;
        }
        EmployeeWithByteArrayObject employeeObject = (EmployeeWithByteArrayObject)object;

        if ((this.getPhotos() == null) && (employeeObject.getPhotos() != null)) {
            return false;
        }
        if ((employeeObject.getPhotos() == null) && (this.getPhotos() != null)) {
            return false;
        }

        /**
         * Note: do not use Vector.contains() for byte[] arrays since each .getBytes() will return
         * a different hash-value and will not pass the embedded (==) during the .contain check.
         * You must check each base64 byte in sequence
         */
        if ((this.getID() == employeeObject.getID()) && (((this.getPhotos() == null) && (employeeObject.getPhotos() == null)) ||//
                (this.getPhotos().isEmpty() && employeeObject.getPhotos().isEmpty())) ) {
            return true;
        }

        boolean equal = true;


        // hash equality changes
        for (int i = 0; i < getPhotos().size(); i++) {
            try{
                equal = equal && equalByteArrays((Byte[])getPhotos().get(i), (Byte[])employeeObject.getPhotos().get(i));
            }catch(ClassCastException e){
                equal = equal && equalDataHandlers((DataHandler)getPhotos().get(i), (DataHandler)employeeObject.getPhotos().get(i));
            }
        }
        return equal;
    }

    private boolean equalDataHandlers(DataHandler data, DataHandler data2){
        if(!data.getContentType().equals(data2.getContentType())){
            return false;
        }
        try {
            Object obj1 =  data.getContent();
            Object obj2 =  data2.getContent();
            if(data.getContent() instanceof ByteArrayInputStream && data2.getContent() instanceof ByteArrayInputStream){
                ByteArrayInputStream controlStream = ((ByteArrayInputStream)data.getContent());
                ByteArrayInputStream testStream = ((ByteArrayInputStream)data2.getContent());
                if(controlStream.available() != testStream.available()){
                    return false;
                }

                Byte[] controlBytes = new Byte[controlStream.available()];
                Byte[] testBytes = new Byte[testStream.available()];

                if(!equalByteArrays(controlBytes, testBytes)){
                    return false;
                }

            }else{
                if(!data.getContent().equals(data2.getContent())){
                   return false;
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    // override the contains check on a Vector of byte[] arrays - see TypeDirectMappingTestSuite
    private boolean equalByteArrays(Byte[] array1, Byte[] array2) {
        if (array1.length != array2.length) {
            return false;
        }

        // check each base64 byte in sequence
        for (int i = 0; i < array1.length; i++) {
            if (!(array1[i].equals(array2[i]))) {
                return false;
            }
        }

        return true;
    }
}
