package com.capgemini.reports.changeobjects;

import com.capgemini.framework.common.TeamcenterDateFormatter;
import com.capgemini.framework.teamcenter.exceptions.KurtException;
import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException;
import com.capgemini.framework.teamcenter.object.pom.status.StatusEnum;
import com.capgemini.framework.teamcenter.policies.PolicyLocation;
import com.capgemini.framework.teamcenter.queries.saved.modelobject.ItemRevisionQuery;
import com.capgemini.reports.AbstractTeamcenterTest;
import com.capgemini.reports.changeobjects.change.TcChangeRequestRevision;
import com.capgemini.reports.snecmaobjects.product.ProductRevision;
import com.capgemini.reports.teamcenter.queries.saved.UnitQuery;
import com.capgemini.reports.workflows.Task;
import com.teamcenter.schemas.soa._2006_03.exceptions.ServiceException;
import com.teamcenter.soa.client.model.strong.ItemRevision;
import lombok.extern.slf4j.Slf4j;
import org.junit.Assert;
import org.junit.Test;

import java.util.List;


@Slf4j
public class UnitRevisionTest extends AbstractTeamcenterTest {

    private static final String UNIT_REV = "C";
    private static final String UNIT_ID = "MOD163427";
    private static final String UNIT_ID_WITH_GEL = "MOD120174";// "MOD143898"; // This one has a Workflow attached which is a 'Gel de Unit'
    private static final String UNIT_ID_WITH_SO_CURRENT = "00041717"; // This one is currently going through a 'Unit-Validation UNIT par Services officiels' Workflow
    private static final String UNIT_ID_WITH_SO_FINISHED = "00041694"; // This one has fully gone through a 'Unit-Validation UNIT par Services officiels' Workflow

    /**
     * JUnit test.
     *
     * @throws NoTeamcenterConnectionException should not happen
     */
    @Test
    public void unitRevisionTest() throws NoTeamcenterConnectionException {
        // Obtain the itemRev
        List<ItemRevision> results = new ItemRevisionQuery(getSession()).searchIDAndRevision(UNIT_ID, UNIT_REV).findAll();
        Assert.assertFalse(results.isEmpty());
        ItemRevision tcUnit = results.get(0);
        // Build It
        UnitRevision unit = UnitRevision.build(getSession(), tcUnit);

        // Test it
        Assert.assertNotNull(unit.getItemId());
        log.info("getItemId= " + unit.getItemId());
        Assert.assertEquals(UNIT_ID, unit.getItemId());

        Assert.assertNotNull(unit.getName());
        log.info("getName= " + unit.getName());
        Assert.assertFalse(unit.getName().isEmpty());

        Assert.assertNotNull(unit.getRevision());
        log.info("getRevision= " + unit.getRevision());
        Assert.assertEquals(UNIT_REV, unit.getRevision());

        Assert.assertNotNull(unit.getType());
        log.info("getType= " + unit.getType());
        Assert.assertFalse(unit.getType().isEmpty());

        Assert.assertNotNull(unit.getUid());
        log.info("getUid= " + unit.getUid());
        Assert.assertFalse(unit.getUid().isEmpty());

        Assert.assertNotNull(unit.getUnitRange());
        log.info("unitRange= " + unit.getUnitRange());
        Assert.assertFalse(unit.getUnitRange().isEmpty());

        log.info("isExceptionnel= " + unit.isExceptionnel());
        Assert.assertTrue(unit.isExceptionnel());

        // Change request
        Assert.assertNotNull(unit.getChangeRequestsList());
        log.info("getChangeRequestsList= " + unit.getChangeRequestsList());
        Assert.assertFalse(unit.getChangeRequestsList().isEmpty());
        for (TcChangeRequestRevision request : unit.getChangeRequestsList()) {
            log.info(" + TcChangeRequestRevision ID = {}, Rev={}", request.getItemId(), request.getRevisionId());
        }

        // Generics
        Assert.assertNotNull(unit.getGenerics());
        log.info("getGenerics= " + unit.getGenerics());
        Assert.assertFalse(unit.getGenerics().isEmpty());
        // Release status
        Assert.assertNotNull(unit.getReleaseStatusContainingMaturity());
        log.info("getReleaseStatusContainingMaturity = " + unit.getReleaseStatusContainingMaturity());
        Assert.assertFalse(unit.getReleaseStatusContainingMaturity().isEmpty()); // there should be some maturity status
        Assert.assertNotNull(unit.getTechnicalDocGel());
        log.info("getTechnicalDocGel = " + unit.getTechnicalDocGel());
    }

    /**
     * JUnit test for max query size.
     *
     * @throws ServiceException should not happen
     * @throws KurtException    should not happen
     */
    @Test
    public void testUnitExceptionnel() throws ServiceException, KurtException {
        getSession().setObjectPropPolicy(R20_POLICY_LIGHT);
        // Fetch an EXCEPTIONAL Unit
        List<ItemRevision> result = new UnitQuery(getSession()).searchID("00065685").findAll();
        ItemRevision unit = result.get(0);
        // Build it
        UnitRevision builtUnit = UnitRevision.build(getSession(), unit);
        // Now test it
        Assert.assertTrue(builtUnit.isExceptionnel());
    }

    /**
     * JUnit test for max query size.
     *
     * @throws ServiceException should not happen
     * @throws KurtException    should not happen
     */
    @Test
    public void testUnit87() throws ServiceException, KurtException {
        List<ItemRevision> result = new UnitQuery(getSession()).addEndItemID("35R0").findAll();
        Assert.assertTrue(result.size() > 50);
    }

    /**
     * JUnit test.
     *
     * @throws NoTeamcenterConnectionException should not happen
     */
    @Test
    public void loadWorkflowsValidationUnitParSOTest() throws NoTeamcenterConnectionException {
        List<ItemRevision> results = new ItemRevisionQuery(getSession()).searchIDAndRevision(UNIT_ID_WITH_SO_FINISHED, "A").findAll();
        Assert.assertFalse(results.isEmpty());
        ItemRevision tcUnit = results.get(0);
        UnitRevision unit = UnitRevision.build(getSession(), tcUnit);

        log.info("Building workflows...");
        Assert.assertFalse(unit.getWorkflowsValidationUnitParSO().isEmpty());

        log.info("Browsing {} workflows", unit.getWorkflowsValidationUnitParSO().size());
        for (Task task : unit.getWorkflowsValidationUnitParSO()) {
            Assert.assertNotNull(task);
            String lastModDate = TeamcenterDateFormatter.formatCalendarToFrench(task.getLastModDate());
            String creationDate = TeamcenterDateFormatter.formatCalendarToFrench(task.getCreationDate());
            String owner = task.getOwningUser() == null ? null : task.getOwningUser().getName();
            String validator = task.getLastModUser() == null ? null : task.getLastModUser().getName();
        }
    }

    /**
     * JUnit test.
     *
     * @throws NoTeamcenterConnectionException should not happen
     */
    @Test
    public void loadWorkflowsValidationUnitParSOTestCURRENT() throws NoTeamcenterConnectionException {
        List<ItemRevision> results = new ItemRevisionQuery(getSession()).searchIDAndRevision(UNIT_ID_WITH_SO_CURRENT, "A").findAll();
        Assert.assertFalse(results.isEmpty());
        ItemRevision tcUnit = results.get(0);
        UnitRevision unit = UnitRevision.build(getSession(), tcUnit);

        log.info("Building workflows...");
        Assert.assertFalse(unit.getWorkflowsValidationUnitParSO().isEmpty());

        log.info("Browsing {} workflows", unit.getWorkflowsValidationUnitParSO().size());
        for (Task task : unit.getWorkflowsValidationUnitParSO()) {
            Assert.assertNotNull(task);
            String lastModDate = TeamcenterDateFormatter.formatCalendarToFrench(task.getLastModDate());
            String creationDate = TeamcenterDateFormatter.formatCalendarToFrench(task.getCreationDate());
            String owner = task.getOwningUser() == null ? null : task.getOwningUser().getName();
            String validator = task.getLastModUser() == null ? null : task.getLastModUser().getName();
        }
    }

    @Test
    public void unitRevisionTestGel() throws NoTeamcenterConnectionException {
        List<ItemRevision> results = new ItemRevisionQuery(getSession()).searchIDAndRevision(UNIT_ID_WITH_GEL, "D").findAll();
        Assert.assertFalse(results.isEmpty());
        ItemRevision tcUnit = results.get(0);
        UnitRevision unit = UnitRevision.build(getSession(), tcUnit);
        log.info("getItemId= " + unit.getItemId());
        Assert.assertNotNull(unit.getItemId());
        Assert.assertEquals(UNIT_ID_WITH_GEL, unit.getItemId());

        Assert.assertNotNull(unit.getTechnicalDocGel());
    }

    @Test
    public void testChooseRevisionOfUnitFromRange() throws NoTeamcenterConnectionException {
        // Configuration
        String productId = "29R0";
        String productRevisionId = "B";
        String range = "240";

        // Query
        List<ItemRevision> productRevisions =
                new ItemRevisionQuery(getSession()).searchIDAndRevision(productId, productRevisionId).findAll();

        // Build objects
        ProductRevision product = new ProductRevision(getSession(), productRevisions.get(0));

        // Method to test
        UnitRevision result = UnitRevision.chooseRevisionOfUnitFromRange(range, product.getUnits(), StatusEnum.J3B);

        // Checks
        Assert.assertNotNull(result);
        Assert.assertEquals("Id is not equals to the expected value.", "MOD113586", result.getItemId());
        Assert.assertEquals("RevisionId is not equals to the expected value.", "E", result.getRevision());
    }

    @Override
    public PolicyLocation getPropertyPolicyIdentifier() {
        return R20_POLICY_FULL;
    }

}
