package com.capgemini.reports.builder;

import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum;
import com.capgemini.reports.definition.r23report.ExecutionR23;
import com.capgemini.reports.exceptions.InsufficientParametersException;
import com.capgemini.reports.reports.parameters.EffectivityDate;
import com.capgemini.reports.reports.parameters.Generics;
import com.capgemini.reports.reports.parameters.MonoMulti;
import com.capgemini.reports.reports.parameters.ProductUnit;
import com.google.common.base.Joiner;

import java.util.Map;

/**
 * Reconstructs a R23 report from BOM parameters. Generic parameters are optional.
 */
public class R23Builder implements ReportBuilder {

    @Override
    public ExecutionR23 build(Map<ReportCriteriaEnum, String> data) throws InsufficientParametersException {
        // Get the request raw data
        String product = data.get(ReportCriteriaEnum.PRODUCT);
        String monoMultiStr = data.get(ReportCriteriaEnum.MONO_MULTI);
        String generic = data.get(ReportCriteriaEnum.GENERIC);
        String genericAssemb = data.get(ReportCriteriaEnum.GENERIC_ASSEMB);
        String effectivityStr = data.get(ReportCriteriaEnum.EFFECTIVITY_DATE);
        String superModelStr = data.get(ReportCriteriaEnum.SUPERMODEL);
        String isWithFrozenUnitStr = data.get(ReportCriteriaEnum.WITH_FROZEN_UNIT);
        String unitStr = data.get(ReportCriteriaEnum.UNIT);
        String fromUnitStr = data.get(ReportCriteriaEnum.FROM_UNIT);
        String frozenSinceLessThanStr = data.get(ReportCriteriaEnum.UNITS_FROZEN_SINCE_LESS_THAN);

        // Check presence of all required args
        if (product == null || monoMultiStr == null) {
            String dataStr = Joiner.on('|').withKeyValueSeparator("=").useForNull("null").join(data);
            throw new InsufficientParametersException("Missing parameter for R23 launch. Obtained: " + dataStr);
        }
        ProductUnit aProductUnit = new ProductUnit(product, null);
        Generics aGeneric = new Generics(aProductUnit, generic, genericAssemb);
        MonoMulti aMonoMulti = MonoMulti.build(monoMultiStr);
        EffectivityDate anEffectivity = new EffectivityDate(effectivityStr);
        boolean isSuperModelBOM = Boolean.parseBoolean(superModelStr);
        boolean isWithFrozenUnit = Boolean.parseBoolean(isWithFrozenUnitStr);
        ProductUnit productUnitForUnit = new ProductUnit(product, unitStr);
        ProductUnit productUnitFromUnit = new ProductUnit(product, fromUnitStr);


        // Build the report
        return new ExecutionR23(aProductUnit, aGeneric, aMonoMulti, anEffectivity, isSuperModelBOM, isWithFrozenUnit, productUnitForUnit, productUnitFromUnit, frozenSinceLessThanStr);
    }

}
