package com.capgemini.reports.builder;

import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum;
import com.capgemini.reports.definition.r21report.ExecutionR21;
import com.capgemini.reports.exceptions.InsufficientParametersException;
import com.capgemini.reports.reports.parameters.DualGenerics;
import com.capgemini.reports.reports.parameters.EffectivityDate;
import com.capgemini.reports.reports.parameters.ProductUnit;
import com.google.common.base.Joiner;

import java.util.Map;

/** Builds a R21 Report from BOM Configuration. Both Gen & GenAssemb must be there. */
public class R21Builder implements ReportBuilder {

    @Override
    public ExecutionR21 build(Map<ReportCriteriaEnum, String> data) throws InsufficientParametersException {
        // Get the request raw data
        String product = data.get(ReportCriteriaEnum.PRODUCT);
        String unitStr = data.get(ReportCriteriaEnum.UNIT);
        String generic = data.get(ReportCriteriaEnum.GENERIC);
        String genericAssemb = data.get(ReportCriteriaEnum.GENERIC_ASSEMB);
        String effectivityStr = data.get(ReportCriteriaEnum.EFFECTIVITY_DATE);

        // Check presence of all required args
        if (product == null || unitStr == null || generic == null || genericAssemb == null) {
            String dataStr = Joiner.on('|').withKeyValueSeparator("=").useForNull("null").join(data);
            throw new InsufficientParametersException("Missing parameter for R21 launch. Obtained: " + dataStr);
        }

        // Present args in correct format
        int unit;
        try {
            unit = Integer.parseInt(unitStr);
        } catch (NumberFormatException e) {
            throw new InsufficientParametersException("Unit parameter is not an int: " + unitStr, e);
        }
        ProductUnit aProductUnit = new ProductUnit(product, unit);
        DualGenerics aGeneric = new DualGenerics(aProductUnit, generic, genericAssemb);
        EffectivityDate anEffectivity = new EffectivityDate(effectivityStr);

        // Build the report
        return new ExecutionR21(aProductUnit, aGeneric, anEffectivity);
    }

}
