package com.oguerreiro.resilient.expression;

import java.math.BigDecimal;

import com.oguerreiro.resilient.domain.Unit;
import com.oguerreiro.resilient.domain.Variable;
import com.oguerreiro.resilient.repository.EmissionFactorRepository;

public class UnitConverterExpressionContext extends ExpressionContext {
  private static final String INPUT_YEAR = "year";
  private static final String INPUT_VALUE = "value";
  private static final String INPUT_FROM_UNIT = "fromUnit";
  private static final String INPUT_TO_UNIT = "toUnit";
  private static final String INPUT_VARIABLE = "variable";
  private static final String INPUT_CLASS_CODE = "classCode";

  private static final String FUNCTION_EMISSIONFACTOR = "FEmission";

  private EmissionFactorRepository emissionfactorRepository;

  /**
   * Sets the inputs names and types. Basic Context for validation
   */
  private UnitConverterExpressionContext(EmissionFactorRepository emissionfactorRepository) {
    this(null, null, null, null, null, null, emissionfactorRepository);
  }

  private UnitConverterExpressionContext(Integer year, Object value, Unit fromUnit, Unit toUnit, Variable variable,
      String classCode, EmissionFactorRepository emissionfactorRepository) {
    this.addInput(INPUT_YEAR, Integer.class, year);
    this.addInput(INPUT_VALUE, BigDecimal.class, value);
    this.addInput(INPUT_FROM_UNIT, Unit.class, fromUnit);
    this.addInput(INPUT_TO_UNIT, Unit.class, toUnit);
    this.addInput(INPUT_VARIABLE, Variable.class, variable);
    this.addInput(INPUT_CLASS_CODE, String.class, classCode);

    this.addInput(FUNCTION_EMISSIONFACTOR, FunctionEmissionFactor.class,
        new FunctionEmissionFactor(year, emissionfactorRepository));

    this.emissionfactorRepository = emissionfactorRepository;
  }

  public static UnitConverterExpressionContext create(EmissionFactorRepository emissionfactorRepository, Integer year,
      Object value, Unit fromUnit, Unit toUnit, Variable variable, String classCode) {
    return new UnitConverterExpressionContext(year, value, fromUnit, toUnit, variable, classCode,
        emissionfactorRepository);
  }

  public static UnitConverterExpressionContext create(EmissionFactorRepository emissionfactorRepository) {
    return new UnitConverterExpressionContext(emissionfactorRepository);
  }

  public class FunctionEmissionFactor {
    private EmissionFactorRepository emissionfactorRepository;
    private Integer currentYear;

    public FunctionEmissionFactor(Integer currentYear, EmissionFactorRepository emissionfactorRepository) {
      this.emissionfactorRepository = emissionfactorRepository;
      this.currentYear = currentYear;
    }

    public Double factor(Integer year, String code) {
      return Double.valueOf(0.20);
    }

    public Double factor(String code) {
      return this.factor(currentYear, code);
    }
  }
}
