package com.capgemini.reports.documentationobjects;

import com.capgemini.framework.teamcenter.authent.TcSession;
import com.capgemini.framework.teamcenter.object.pom.status.TcReleaseStatus;
import com.teamcenter.soa.client.model.strong.Form;
import com.teamcenter.soa.client.model.strong.Item;
import com.teamcenter.soa.client.model.strong.ItemRevision;
import com.teamcenter.soa.client.model.strong.ReleaseStatus;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import static com.capgemini.framework.teamcenter.object.SnecmaObjectProperties.NIVEAU_SENSIBILITE;

/**
 * Abstract class for all objects of type Document. Contains Id, Revision, Name and Type.
 */
public abstract class AbstractDoc implements Serializable {
    private static final long serialVersionUID = -3082137888946282380L;
    protected final ItemRevision itemRevision;
    protected final TcSession session;

    private List<TcReleaseStatus> statuses;
    private Form masterFormRev;

    public AbstractDoc(final TcSession session, final ItemRevision itemRevision) {
        this.session = session;
        this.itemRevision = itemRevision;
    }

    public String getUid() {
        return itemRevision.getUid();
    }

    public String getType() {
        return itemRevision.getTypeObject().getName();
    }

    public String getDocId() {
        return itemRevision.get_item_id();
    }

    public String getRevision() {
        return itemRevision.get_item_revision_id();
    }

    public String getName() {
        return itemRevision.get_object_name();
    }

    public Calendar getDateCreation() {
        return itemRevision.get_creation_date();
    }

    public Item getItem() {
        session.loadProperties(itemRevision, "items_tag");
        Item item = itemRevision.get_items_tag();
        session.loadProperties(item);
        return item;
    }


    public Form getMasterForm() {
        Item item = getItem();
        session.loadProperties(item, "item_master_tag");
        Form masterTag = item.get_item_master_tag();
        session.loadProperties(masterTag);
        return masterTag;
    }

    public Form getMasterFormRev() {
        if (masterFormRev == null) {
            masterFormRev = itemRevision.get_item_master_tag();
            session.loadProperties(masterFormRev);
        }
        return masterFormRev;
    }

    public List<TcReleaseStatus> getStatus() {
        if (statuses == null) {
            statuses = new ArrayList<>();
            session.loadProperties(itemRevision, "release_status_list");
            ReleaseStatus[] releaseStatuses = itemRevision.get_release_status_list();
            session.loadProperties(releaseStatuses);
            for (ReleaseStatus releaseStatus : releaseStatuses) {
                TcReleaseStatus tcReleaseStatus = new TcReleaseStatus(session, releaseStatus);
                statuses.add(tcReleaseStatus);
            }
        }
        return statuses;
    }

    public String getNiveauSensibilite() {
        session.loadProperties(itemRevision, NIVEAU_SENSIBILITE);
        return itemRevision.getPropertyObject(NIVEAU_SENSIBILITE).getStringValue();
    }

    @Override
    public String toString() {
        return this.getType() + " " + this.getDocId() + "/" + this.getRevision();
    }

    /**
     * Visitor method.
     *
     * @param docVisitor a {@link IDocVisitor}
     * @param <T>        anything you may want to return from your visit
     * @return the outcome of the visit
     */
    public abstract <T> T accept(final IDocVisitor<T> docVisitor);
}
