package com.capgemini.reports.reports.parameters.checker;

import com.capgemini.framework.teamcenter.authent.TcSession;
import com.capgemini.reports.exceptions.InvalidUserInputException;
import com.capgemini.reports.exceptions.NotFoundException;
import com.capgemini.reports.exceptions.UserInputErrorEnum;
import com.capgemini.reports.reports.parameters.DualGenerics;
import com.capgemini.reports.reports.parameters.IChecker;
import com.capgemini.reports.reports.parameters.ProductUnit;
import com.capgemini.reports.teamcenter.ObjectInfoHelper;
import com.capgemini.reports.teamcenter.ObjectInfoLoader;
import com.teamcenter.soa.client.model.strong.ItemRevision;

import java.util.List;

/**
 * Checks some conditions on a Generic for the R21 report.
 */
public class GenericConditionR21Checker implements IChecker {

    private final ProductUnit productUnit;
    private final DualGenerics dualGenerics;

    /**
     * Define productUnit and dualGenerics configuration.
     *
     * @param productUnit  a {@link ProductUnit}
     * @param dualGenerics a {@link DualGenerics}
     */
    public GenericConditionR21Checker(final ProductUnit productUnit, final DualGenerics dualGenerics) {
        this.productUnit = productUnit;
        this.dualGenerics = dualGenerics;
    }


    @Override
    public void check(final TcSession session) throws InvalidUserInputException {
        checkGenericConditionR21(session);
        checkGenericAssembConditionR21(session);
    }

    private void checkGenericConditionR21(final TcSession session) throws InvalidUserInputException {

        // Parse user input
        productUnit.parseUserUnit();
        int userUnit = productUnit.getUnit();

        ObjectInfoLoader objectInfoLoader = new ObjectInfoLoader(session);
        // Get existing units in Database
        try {
            List<ItemRevision> genericsRevision = objectInfoLoader.getGenericUnderProduct(dualGenerics.asGeneric(), productUnit);
            if (genericsRevision == null || genericsRevision.isEmpty()) {
                throw new InvalidUserInputException(UserInputErrorEnum.GENERIC_DOES_NOT_EXIST);
            }
            boolean isGenericHasAnUnitRevision = ObjectInfoHelper.getClosestGenerics(session, dualGenerics.asGeneric().getID(), userUnit, genericsRevision);

            if (!isGenericHasAnUnitRevision) {
                throw new InvalidUserInputException(UserInputErrorEnum.NO_DATA_COULD_BE_EXTRACTED_FOR_GENERIC_PRODUCT_AND_UNIT);
            }
        } catch (NotFoundException e) {
            throw new InvalidUserInputException(UserInputErrorEnum.NO_DATA_COULD_BE_EXTRACTED_FOR_GENERIC_PRODUCT_AND_UNIT, e);
        }

    }

    private void checkGenericAssembConditionR21(final TcSession session) throws InvalidUserInputException {
        // Parse user input
        productUnit.parseUserUnit();
        int userUnit = productUnit.getUnit();

        ObjectInfoLoader objectInfoLoader = new ObjectInfoLoader(session);
        // Get existing units in Database
        try {
            List<ItemRevision> genericsAssembRevision = objectInfoLoader.getGenericAssembUnderProduct(dualGenerics.asGenericAssemb(), productUnit);
            if (genericsAssembRevision == null || genericsAssembRevision.isEmpty()) {
                throw new InvalidUserInputException(UserInputErrorEnum.GENERIC_ASSEMB_DOES_NOT_EXIST);
            }
            boolean isGenericHasAnUnitRevision =
                    ObjectInfoHelper.getClosestGenerics(session, dualGenerics.asGenericAssemb().getID(), userUnit, genericsAssembRevision);

            if (!isGenericHasAnUnitRevision) {
                throw new InvalidUserInputException(UserInputErrorEnum.NO_DATA_COULD_BE_EXTRACTED_FOR_GENERIC_PRODUCT_AND_UNIT);
            }
        } catch (NotFoundException e) {
            throw new InvalidUserInputException(UserInputErrorEnum.NO_DATA_COULD_BE_EXTRACTED_FOR_GENERIC_PRODUCT_AND_UNIT, e);
        }
    }

}
