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

import com.capgemini.framework.teamcenter.authent.TcSession;
import com.capgemini.framework.teamcenter.queries.saved.modelobject.ItemQuery;
import com.capgemini.reports.exceptions.InvalidUserInputException;
import com.capgemini.reports.exceptions.UserInputErrorEnum;
import com.capgemini.reports.reports.parameters.IChecker;
import com.teamcenter.soa.client.model.strong.Item;
import com.teamcenter.soa.client.model.strong.ItemRevision;

import java.util.List;
import java.util.regex.Pattern;

/**
 * Checks if the provided itemId belongs to one of the types provided. <br>
 * Note: the provided types must be Item Types, not ItemRevision types (i.e. 'PartAero' or 'Standard' are ok, but not 'PartAero Revision'.
 */
public class ObjectTypeChecker implements IChecker {

    private final String itemId;
    private final String[] typePatterns;

    /**
     * Constructs a checker tht verifies if the type of the Item whose ID is provided matches any of the type filters.<br>
     * Note: the provided types must be Item Types, not ItemRevision types (i.e. 'PartAero' or 'Standard' are ok, but not 'PartAero Revision'.<br>
     * Note2: At least one filter element must be provided.
     * 
     * @param itemId the Id of the Item
     * @param typeFilters the provided types. Each must be {@link Item} Type, not {@link ItemRevision} type (i.e. 'PartAero' or 'Standard' are ok, but not 'PartAero Revision'.
     */
    public ObjectTypeChecker(final String itemId, final String... typeFilters) {
        this.itemId = itemId;
        this.typePatterns = new String[typeFilters.length];
        for (int num = 0; num < typeFilters.length; num++) {
            this.typePatterns[num] = ".*" + typeFilters[num] + ".*";
        }
    }

    @Override
    public void check(final TcSession session) throws InvalidUserInputException {
        if (typePatterns.length == 0) {
            throw new InvalidUserInputException("No Type pattern was specified"); // Should never happen: one must not build a checker without at least one filter element
        }
        List<Item> items = new ItemQuery(session).searchID(itemId).findAll();
        if (items == null || items.isEmpty()) {
            throw new InvalidUserInputException(getErrorMessage());
        }
        for(Item item : items) {
            String actualType = item.getTypeObject().getName();
            for (String type : typePatterns) {
                if (Pattern.matches(type, actualType)) {
                    return; // Type is ok
                }
            }
        }
        // If we findAll here type is not authorised
        throw new InvalidUserInputException(getErrorMessage());
    }

    protected UserInputErrorEnum getErrorMessage() {
        return UserInputErrorEnum.THE_SELECTED_OBJECT_IS_NOT_PERMITTED_ON_THIS_REPORT;
    }
}
