package com.libreecm.db.jpa;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.persistence.*;

import org.apache.chemistry.opencmis.commons.data.AclCapabilities;
import org.apache.chemistry.opencmis.commons.data.CmisExtensionElement;
import org.apache.chemistry.opencmis.commons.data.ExtensionFeature;
import org.apache.chemistry.opencmis.commons.data.RepositoryCapabilities;
import org.apache.chemistry.opencmis.commons.enums.BaseTypeId;
import org.apache.chemistry.opencmis.commons.enums.CmisVersion;
import org.hibernate.annotations.GenericGenerator;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.libreecm.db.jpa.users.AclCapabilitiesImpl;

/**
 * @author Jordi Pérez Bayerri
 *
 */ 
@Entity
@Table(name="repository")
public class Repository extends LibreECMObject implements org.apache.chemistry.opencmis.commons.data.RepositoryInfo{
	/**
	 * 
	 */
	private static final long serialVersionUID = -3719876864024503895L;

	@Id
	@GeneratedValue(generator="hilo-gen")
	@GenericGenerator(name="hilo-gen", strategy="hilo")
	private Integer id;
	
	private String name;
	
	private String description;

	private boolean active;
	
	private boolean accessible;
	
    /**
	 * @return the active
	 */
	public boolean isActive() {
		return active;
	}

	/**
	 * @param active the active to set
	 */
	public void setActive(boolean active) {
		this.active = active;
	}

	/**
	 * @return the accessible
	 */
	public boolean isAccessible() {
		return accessible;
	}

	/**
	 * @param accessible the accessible to set
	 */
	public void setAccessible(boolean accessible) {
		this.accessible = accessible;
	}

	/**
     * Id of the repository's root folder
     */
	private String rootFolderId;
	
	/**
	 * Main Id 
	 */
    private String principalIdAnonymous;
    
    /**
     * Main Id
     */
    private String principalIdAnyone;

    /**
     * Where to locate fisically the repository
     */
    private String thinClientUri;
    
    private AllowableActions actions;
    
    /**
     * Boolean showing there is tasks pending (work in progress)
     */
    private Boolean changesIncomplete;
    /**
     * Token for last change LOG
     */
    private String latestChangeLogToken;
    
    /**
     * Vendor of the repository
     */
    private String vendorName;
    
    /**
     * Comercial Name of the repository product
     */
    private String productName;
    
    /**
     * Comercial version of the repository product
     */
    private String productVersion;
    
    private AclCapabilitiesImpl aclCapabilities;

    private RepositoryCapabilitiesImpl repositoryCapabilities;

	private String cmisVersionSupported;

	private CmisVersion cmisVersion;
	
	/**
     * An array of Id for customized types supporting at this repository
     */
    @Column
    @ElementCollection(targetClass=String.class)
    private List<String> customizedTypes= new ArrayList<String>();

    /**
    * A collection of types changed by this repository
    */
    @ElementCollection(targetClass=BaseTypeId.class)
    private List<BaseTypeId> changesOnType;

	
    @OneToMany
	//@JoinColumn(name="repository_cmis_extensions_id", referencedColumnName="id")
	/**
    * A collection of additional cmis extension elements supported by this repository
    */
	private List<CmisExtensionElementImpl> cmisExtensionElements;    
	 
    @OneToMany
    //@JoinColumn(name="repository_extensions_features_id", referencedColumnName="id")
    /**
    * A collection of additional features supported by this repository
    */
    private List<ExtensionFeatureImpl> extensionFeatures;

	private String typeId;
	
	private String path;
	
	/**
	 * <p>Path is a string representing the position of
	 * repository at the persistence. Examples:</p>
	 * <p>/media/repositories/example/</p>
	 * <p>C:/media/repositories/example/</p>
	 * <p>DBServer/DB/table/</p>
	 * @return the path
	 */
	public String getPath() {
		return path;
	}

	/**
	 * @param path the path to set
	 */
	public void setPath(String path) {
		this.path = path;
	}

	/**
	 * @return the typeId
	 */
	public String getTypeId() {
		return typeId;
	}

	/**
	 * @param typeId the typeId to set
	 */
	public void setTypeId(String typeId) {
		this.typeId = typeId;
	}


    public Repository(){
	}

	public Repository(String id, String name, String description, String rootFolderId, String principalIdAnonymous,
			String principalIdAnyone, String thinClientUri, Boolean changesIncomplete, String latestChangeLogToken,
			String vendorName, String productName, String productVersion, AclCapabilitiesImpl capabilitiesAcl,
			RepositoryCapabilitiesImpl repositoryCapabilities, String cmisVersionSupported, CmisVersion cmisVersion,
			List<String> customizedTypes, List<ExtensionFeatureImpl> extensionFeatures, List<BaseTypeId> changesOnType,
			List<CmisExtensionElementImpl> cmisExtensionElements) {
		super();
		this.id=Integer.parseInt(id);
		this.name = name;
		this.description = description;
		this.rootFolderId = rootFolderId;
		this.principalIdAnonymous = principalIdAnonymous;
		this.principalIdAnyone = principalIdAnyone;
		this.thinClientUri = thinClientUri;
		this.changesIncomplete = changesIncomplete;
		this.latestChangeLogToken = latestChangeLogToken;
		this.vendorName = vendorName;
		this.productName = productName;
		this.productVersion = productVersion;
		this.aclCapabilities = capabilitiesAcl;
		this.repositoryCapabilities = repositoryCapabilities;
		this.cmisVersionSupported = cmisVersionSupported;
		this.cmisVersion = cmisVersion;
		this.customizedTypes = customizedTypes;
		this.extensionFeatures = extensionFeatures;
		this.changesOnType = changesOnType;
		this.cmisExtensionElements = cmisExtensionElements;
	}


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

	public String getDescription() {
		return description;
	}
	
    public void setDescription(String description) {
		this.description=description;
	}

	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name=name;		
	}

	
	public String toString(){
    	return "Repository id:"+getId()
    			+" name "+getName()
    			+" description "+getDescription();
    }

    public void setRootFolder(String id) {
        this.rootFolderId = id;
    }

    public void setAclCapabilities(AclCapabilitiesImpl capabilitiesAcl) {
        this.aclCapabilities = capabilitiesAcl;
    }

    public void setPrincipalIdAnonymous(String id) {
        this.principalIdAnonymous = id;
    }

    public void setPrincipalIdAnyone(String principalIdAnyone) {
        this.principalIdAnyone = principalIdAnyone;
    }

    public String getThinClientUri() {
        return thinClientUri;
    }

    public void setThinClientUri(String thinClientUri) {
        this.thinClientUri = thinClientUri;
    }

    public Boolean getChangesIncomplete() {
        return changesIncomplete;
    }

    public void setChangesIncomplete(Boolean changesIncomplete) {
        this.changesIncomplete = changesIncomplete;
    }

    public List<String> getCustomizedTypes() {
        return customizedTypes;
    }

    public void setChangesOnType(List<BaseTypeId> changesOnType) {
    	this.changesOnType = changesOnType;
    }

    public String getLatestChangeLogToken() {
        return latestChangeLogToken;
    }

    public void setLatestChangeLogToken(String latestChangeLogToken) {
        this.latestChangeLogToken = latestChangeLogToken;
    }

    public String getVendorName() {
        return vendorName;
    }

    public void setVendorName(String vendorName) {
        this.vendorName = vendorName;
    }

    public String getProductName() {
        return productName;
    }

    public void setProductName(String productName) {
        this.productName = productName;
    }

    public String getProductVersion() {
        return productVersion;
    }

    public void setProductVersion(String productVersion) {
        this.productVersion = productVersion;
    }

	public void setCustomizedTypes(ArrayList<String> arrayList) {
		this.customizedTypes=arrayList;
	}
	
	@Override
	public String getId() {
		if (id==null){
			return null;
		}
		return this.id.toString();
	}

	@Override
	public String getRootFolderId() {
		return this.rootFolderId;
	}
	    
	@Override
	public AclCapabilities getAclCapabilities() {
		if (aclCapabilities == null){
			this.aclCapabilities=new AclCapabilitiesImpl();
		}
		return this.aclCapabilities;
	}

	@Override
	public String getCmisVersionSupported() {
		return this.cmisVersionSupported;
	}

	@Override
	public CmisVersion getCmisVersion() {
		return cmisVersion;
	}

	@Override
	public List<BaseTypeId> getChangesOnType() {
		if (this.changesOnType==null){
			this.changesOnType=new ArrayList<BaseTypeId>();
		}
		return changesOnType;
	}

	@Override
	public String getPrincipalIdAnonymous() {
		return this.principalIdAnonymous.toString();
	}

	@Override
	public String getPrincipalIdAnyone() {
		return this.principalIdAnyone.toString();
	}

	public RepositoryCapabilities getRepositoryCapabilities() {
		return repositoryCapabilities;
	}

	public void setRepositoryCapabilities(RepositoryCapabilitiesImpl repositoryCapabilities) {
		this.repositoryCapabilities = repositoryCapabilities;
	}

	public void setRootFolderId(String rootFolderId) {
		this.rootFolderId = rootFolderId;
	}

	public void setCmisVersionSupported(String cmisVersionSupported) {
		this.cmisVersionSupported = cmisVersionSupported;
	}

	public void setCmisVersion(CmisVersion cmisVersion) {
		this.cmisVersion = cmisVersion;
	}
	
	public List<CmisExtensionElementImpl> getCmisExtensionElements() {
		if (this.cmisExtensionElements==null){
			this.cmisExtensionElements=new ArrayList<>();
		}
		return this.cmisExtensionElements;
	} 

	public void setCmisExtensionElements(List<CmisExtensionElementImpl> arg0) {
		this.cmisExtensionElements=arg0;		
	}
 
	/**
	 * Returns a list of CmisExtensionElements from Repository
	 * Deprecated, best use getCmisExtensionElements
	 */
	@Override
	@JsonIgnore
	@Deprecated
	public List<CmisExtensionElement> getExtensions() {
		ArrayList<CmisExtensionElement> array= new ArrayList<CmisExtensionElement>();
		array.addAll(this.cmisExtensionElements);
		return array;
	}

	/**
	 * Sets a list of CmisExtensionElements to Repository
	 * Deprecated, best use setCmisExtensionElements
	 */
	@JsonIgnore
	@Deprecated
	@Override	
	public void setExtensions(List<CmisExtensionElement> extensions){
		this.cmisExtensionElements=new ArrayList<>();
		for (CmisExtensionElement el: extensions){
			this.cmisExtensionElements.add((CmisExtensionElementImpl) el);
		}
	}

	public void setExtensionFeatures(List<ExtensionFeature> extensions) {
	this.extensionFeatures=new ArrayList<ExtensionFeatureImpl>();
	Iterator<ExtensionFeature> it = extensions.iterator();
		while (it.hasNext()){
			this.extensionFeatures.add((ExtensionFeatureImpl) it.next());
		}		
	}
	
	@Override
	public List<ExtensionFeature> getExtensionFeatures() {
		ArrayList<ExtensionFeature> array= new ArrayList<>();
		array.addAll(this.extensionFeatures);
		return array;
	}

	@Override
	@JsonIgnore
	@Deprecated
	public RepositoryCapabilities getCapabilities() {
		return getRepositoryCapabilities();
	}


}