/*
 * Copyright (c) 2012, 2020 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 - 2.3.3 - initial implementation
package org.eclipse.persistence.testing.jaxb.collections;

import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import jakarta.xml.bind.JAXBElement;
import jakarta.xml.bind.annotation.XmlAnyAttribute;
import jakarta.xml.bind.annotation.XmlAnyElement;
import jakarta.xml.bind.annotation.XmlAttribute;
import jakarta.xml.bind.annotation.XmlElement;
import jakarta.xml.bind.annotation.XmlElementRef;
import jakarta.xml.bind.annotation.XmlElementRefs;
import jakarta.xml.bind.annotation.XmlIDREF;
import jakarta.xml.bind.annotation.XmlList;
import jakarta.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class CollectionHolderNillable {

    @XmlElement(nillable = true)
    protected List<Integer> collection1;

    @XmlList
    protected List<String> collection2;

    @XmlElement(nillable = true)
    protected List<Object> collection3;

    @XmlAnyElement
    protected List collection4;

    @XmlElement(nillable = true)
    protected List<CollectionHolderNillable> collection5;

    @XmlElementRefs ({@XmlElementRef(name="root2"), @XmlElementRef(name="root")})
    protected List collection6;

    @XmlElement(name="referenced-id", nillable= true)
    @XmlIDREF
    @XmlList
    protected List<ReferencedObject> collection7;

    @XmlAttribute(name="attribute-referenced-id")
    @XmlIDREF
    public List<ReferencedObject> collection8;

    @XmlElement(nillable = true)
    protected List<CoinEnum> collection9;

    @XmlAnyAttribute
    protected Map collection10;

    @XmlElement(nillable = true)
    protected List<byte[]> collection11;

    public CollectionHolderNillable(){
    }

    public Map getCollection10() {
        return collection10;
    }

    public void setCollection10(Map collection10) {
        this.collection10 = collection10;
    }
    public boolean equals(Object compareObject){

         if(compareObject instanceof CollectionHolderNillable){
             CollectionHolderNillable compareCollectionHolder = ((CollectionHolderNillable)compareObject);
             return compareCollections(collection1, compareCollectionHolder.collection1)
                    && compareCollections(collection2, compareCollectionHolder.collection2)
                    && compareCollections(collection3, compareCollectionHolder.collection3)
                    && compareCollections(collection4, compareCollectionHolder.collection4)
                    && compareCollections(collection5, compareCollectionHolder.collection5)
                    && compareCollections(collection6, compareCollectionHolder.collection6)
                    && compareCollections(collection7, compareCollectionHolder.collection7)
                    && compareCollections(collection8, compareCollectionHolder.collection8)
                    && compareCollections(collection9, compareCollectionHolder.collection9)
                    && compareMaps(collection10, compareCollectionHolder.getCollection10())
                    && compareCollections(collection11, compareCollectionHolder.collection11)
                    ;
         }
         return false;
     }

    private boolean compareMaps(Map map1, Map map2){
        if(map1 == null){
            return map2 == null;
        }else{
            if(map2 == null){
                return false;
            }

            return map1.equals(map2);
        }
    }

     private boolean compareCollections(Collection compareList1, Collection compareList2){
         if(compareList1 == null){
             return compareList2 == null;
         }else{
             if(compareList2 == null){
                 return false;
             }
             if(compareList1.size() != compareList2.size()){
                 return false;
             }
             Iterator iter1 = compareList1.iterator();
             Iterator iter2 = compareList2.iterator();

             while(iter1.hasNext()){
                 if(!(compareItems(iter1.next(), iter2.next()))){
                     return false;
                 }
             }
             return true;
         }

     }

     private boolean compareItems(Object item1, Object item2){

         if(item1 instanceof JAXBElement){
             if(!(item2 instanceof JAXBElement)){
                 return false;
             }
             return compareJAXBElements((JAXBElement)item1, (JAXBElement)item2);
         }else{
             if(item1 == null){
                 if(item2 != null){
                     return false;
                 }
                 return true;
             }else{
                 return item1.equals(item2);
             }
         }
     }

     private boolean  compareJAXBElements(JAXBElement item1, JAXBElement item2){
         if(!(item1.getName().getLocalPart().equals(item2.getName().getLocalPart()))){
             return false;
         }
         if(item1.getValue() == null){
             if(item2.getValue() != null){
                 return false;
             }
         }else if(!(item1.equals(item2))){
             return false;
         }
         return true;
     }
}
