/*
   * (non-Javadoc)
   * @see au.org.aurin.wif.svc.suitability.ManualDemandScenarioService#
   * createManualDemandScenario
   * (au.org.aurin.wif.model.suitability.ManualDemandScenario, java.lang.String)
   */
  public DemandOutcome createDemandOutcomeNew(
      final DemandOutcome demandOutcome, final String projectId)
      throws WifInvalidInputException, WifInvalidConfigException, ParsingException,
          IncompleteDemandOutcomeException {
    if (demandOutcome == null) {
      LOGGER.error("createManualDemandScenario failed: ManualDemandScenario is null or invalid");
      throw new WifInvalidInputException(
          "createManualDemandScenario failed: ManualDemandScenario is null or invalid");
    }
    final WifProject project = projectService.getProject(projectId);
    // final ManualDemandConfig manualdemandConfig = manualdemandConfigService
    // .getManualDemandConfig(projectId);
    final DemandConfig demandConfig = demandConfigService.getDemandConfig(projectId);
    project.setDemandConfig(demandConfig);
    // project.setManualDemandConfig(manualdemandConfig);
    try {
      // ManualDemandScenario = ManualDemandScenarioParser.parse(
      // ManualDemandScenario, manualdemandConfig, project);
    } catch (final Exception e) {
      LOGGER.error("Parsing new scenario failed", e);
      throw new IncompleteDemandOutcomeException("Parsing new scenario failed", e);
    }
    LOGGER.debug("persisting the DemandOutcome={}", demandOutcome.getLabel());
    demandOutcome.setProjectId(projectId);
    final DemandOutcome savedDemandOutcome = demandOutcomeDao.persistDemandOutcome(demandOutcome);
    LOGGER.debug("returning the ManualDemandScenario with id={}", savedDemandOutcome.getId());
    project.getDemandOutcomesMap().put(savedDemandOutcome.getId(), savedDemandOutcome.getLabel());
    wifProjectDao.updateProject(project);

    return savedDemandOutcome;
  }
  public DemandOutcome createDemandOutcome(
      final List<AreaRequirement> outcome, final String projectId)
      throws WifInvalidInputException, WifInvalidConfigException {
    final DemandOutcome newDemandOutcome = new DemandOutcome();
    newDemandOutcome.setLabel("automated-manualdemand");
    LOGGER.debug("creating a new ManualDemandScenario={}", newDemandOutcome.getLabel());
    final WifProject project = projectService.getProject(projectId);
    newDemandOutcome.setProjectId(project.getId());
    for (final AreaRequirement areaRequirement : outcome) {
      // final ManualAreaRequirement manualAreaRequirement = new
      // ManualAreaRequirement();
      // manualAreaRequirement.setAllocationLU(areaRequirement.getAllocationLU());
      // manualAreaRequirement.setRequiredArea(areaRequirement.getRequiredArea());
      // manualAreaRequirement.setProjection(areaRequirement.getProjection());

      areaRequirement.setProjectionLabel(areaRequirement.getProjection().getLabel());

      newDemandOutcome.addAreaRequirenment(areaRequirement);
      LOGGER.info(
          "recreating manually required area for land use  {} in projection "
              + areaRequirement.getProjection().getLabel()
              + " is : {}",
          areaRequirement.getAllocationLU().getLabel(),
          areaRequirement.getRequiredArea());
    }

    final DemandOutcome savedDemandOutcome =
        demandOutcomeDao.persistDemandOutcome(newDemandOutcome);
    LOGGER.debug("returning the ManualDemandScenario with id={}", savedDemandOutcome.getId());
    return savedDemandOutcome;
  }
 /**
  * Load wif project.
  *
  * @throws WifInvalidConfigException the wif invalid config exception
  * @throws Exception the exception
  */
 @BeforeClass(
     enabled = true,
     groups = {"setup", "geo", "database"})
 public void loadWifProject() throws WifInvalidConfigException, Exception {
   project = projectService.getProject(WifKeys.TEST_PROJECT_ID);
   Assert.assertNotNull(project);
   Assert.assertNotNull(project.getSuitabilityConfig());
   final String uazDBTable = project.getSuitabilityConfig().getUnifiedAreaZone();
   featureStore = geodataFinder.getFeatureStorefromDB(uazDBTable);
 }
  /**
   * Parses the allocation scenario test.
   *
   * @throws Exception the exception
   */
  @Test(
      enabled = true,
      groups = {"demand", "database", "couchdb"})
  public void parseAllocationScenarioTest() throws Exception {

    AllocationScenario allocationScenario =
        allocationScenarioDao.findAllocationScenarioById(WifKeys.TEST_ALLOCATION_SCENARIO_ID);
    WifProject project = wifProjectDao.findProjectById(allocationScenario.getProjectId());
    SuitabilityScenario suitabilityScenario =
        suitabilityScenarioDao.findSuitabilityScenarioById(
            allocationScenario.getSuitabilityScenarioId());
    Assert.assertNotNull(suitabilityScenario);
    DemandConfig demandConfig = demandConfigDao.findDemandConfigById(project.getDemandConfigId());
    Assert.assertNotNull(demandConfig);

    DemandScenario demandScenario =
        demandScenarioDao.findDemandScenarioById(allocationScenario.getDemandScenarioId());
    Assert.assertNotNull(demandScenario);

    // Parsing components
    project = projectParser.parse(project);
    suitabilityScenario = suitabilityParser.parseSuitabilityScenario(suitabilityScenario, project);
    demandConfig = demandSetupParser.parse(demandConfig, project);
    demandScenario = demandScenarioParser.parse(demandScenario, demandConfig, project);
    demandScenario = demandScenarioParser.parseAreaRequirements(demandScenario);
    allocationScenario.setDemandScenario(demandScenario);
    allocationScenario = allocationParser.parse(allocationScenario, project);
    // Checking mapping

    String AllocationConfigsId = project.getAllocationConfigsId();

    LOGGER.info("getting the AllocationConfig with ID={}", AllocationConfigsId);
    AllocationConfigs allocationConfig =
        AllocationConfigsDao.findAllocationConfigsById(AllocationConfigsId);

    Assert.assertNotNull(allocationScenario.getLandUseOrderMap());
    Assert.assertNotNull(allocationConfig.getAllocationColumnsMap());
    // Checking allocationLU associations
    AllocationLU resLU = project.getExistingLandUseByLabel("Low Density Res.");
    Assert.assertNotNull(resLU.getAllocationFeatureFieldName());
    Assert.assertNotEquals(resLU.getAreaRequirements().size(), 0);
  }
  /**
   * Gets the allocation rule.
   *
   * @return the allocation rule
   * @throws Exception the exception
   */
  @Test(
      enabled = true,
      groups = {"setup", "geo", "database"})
  public void getAllocationRule() throws Exception {

    LOGGER.debug("getAllocationRule: {}");
    final AllocationScenario allocationScenario =
        allocationScenarioService.getAllocationScenario(WifKeys.TEST_ALLOCATION_SCENARIO_ID);
    final AllocationLU residentiallu = project.getExistingLandUseByLabel("Conservation");
    final String existingLULabel = project.getExistingLUAttributeName();
    final String scoreLabel = residentiallu.getAssociatedLU().getFeatureFieldName();

    final ALURule rule =
        geodataFilterer.getAllocationRule(
            residentiallu, allocationScenario, scoreLabel, existingLULabel, "", "", null, 0.0);
    final Query ruleQuery = rule.getRuleQuery();
    // ruleQuery.
    final SimpleFeatureCollection sortedUazCollection =
        featureStore.getFeatures(rule.getRuleQuery());
    LOGGER.debug("sortedUazCollection size: {}", sortedUazCollection.size());
    // Assert.assertEquals(sortedUazCollection.size(), 7834);
    final SimpleFeatureIterator its = sortedUazCollection.features();
    // 2. for each ORDERED UAZ
    int remaining = 0;
    final String areaLabel = allocationScenario.getWifProject().getAreaLabel();
    while (its.hasNext() && remaining < 10) {
      // 3. while there is a still area to allocate
      final SimpleFeature uazFeature = its.next();

      final String id = uazFeature.getID();
      LOGGER.debug("Allocating feature id: {}", id);
      final Double featureArea = (Double) uazFeature.getAttribute(areaLabel);
      LOGGER.debug(
          "feature suitability score= {}, feature area = {},",
          uazFeature.getAttribute(scoreLabel),
          featureArea);
      remaining++;
    }
  }
 /*
  * (non-Javadoc)
  * @see
  * au.org.aurin.wif.svc.ManualDemandScenarioService#deleteManualDemandScenario
  * (java.lang.String, java.lang.String)
  */
 public void deleteDemandOutcome(final String id, final String projectId)
     throws WifInvalidInputException, WifInvalidConfigException, ParsingException {
   LOGGER.info("deleting the ManualDemandScenario with ID={}", id);
   final DemandOutcome demandOutcome = demandOutcomeDao.findDemandOutcomeById(id);
   if (demandOutcome.getProjectId().equals(projectId)) {
     // Deleting associated area requirements
     final List<AreaRequirement> requirements =
         areaRequirementDao.getAreaRequirements(demandOutcome.getId());
     for (final AreaRequirement areaRequirement : requirements) {
       areaRequirementDao.deleteAreaRequirement(areaRequirement);
     }
     demandOutcomeDao.deleteDemandOutcome(demandOutcome);
     final WifProject project = projectService.getProject(projectId);
     project.getDemandOutcomesMap().remove(id);
     wifProjectDao.updateProject(project);
   } else {
     LOGGER.error(
         "illegal argument, the ManualDemandScenario supplied doesn't belong to project: "
             + projectId);
     throw new WifInvalidInputException(
         "illegal argument, the ManualDemandScenario supplied doesn't belong to project: "
             + projectId);
   }
 }
  /*
   * (non-Javadoc)
   * @see au.org.aurin.wif.svc.report.ReportService#getAllocationAnalysisReport(
   * au.org.aurin.wif.model.allocation.AllocationScenario)
   */
  public AllocationAnalysisReport getAllocationAnalysisReport(
      final AllocationScenario allocationScenario)
      throws WifInvalidInputException, WifInvalidConfigException, ParsingException {
    LOGGER.info("getAllocationAnalysisReport for: {}", allocationScenario.getLabel());
    final AllocationAnalysisReport allocationAnalysisReport = new AllocationAnalysisReport();

    final WifProject project = allocationScenario.getWifProject();
    final AllocationConfig allocationConfig = project.getAllocationConfig();
    final String projectId = allocationScenario.getProjectId();
    allocationAnalysisReport.setReportType(allocationScenario.getDocType());
    allocationAnalysisReport.setLabel(project.getName());
    allocationAnalysisReport.setScenarioLabel(allocationScenario.getDocType());
    allocationAnalysisReport.setProjectId(allocationScenario.getProjectId());

    // Getting land use information
    LOGGER.info("Getting land use information: {}");
    final DemandConfig demandConfig = demandConfigService.getDemandConfig(projectId);
    LOGGER.info("Associated demandConfigId: {}", demandConfig.getId());
    final TreeSet<Projection> projections = new TreeSet<Projection>(new YearComparator());
    projections.addAll(demandConfig.getProjections());
    final Projection current = projections.first();
    LOGGER.info("current year projection: {}", current.getLabel());
    // setting up taking into account current projection year is not a
    // projection by itself,per se,
    final NavigableSet<Projection> projectedSet = projections.tailSet(projections.first(), false);
    final Set<AllocationLU> allocationLandUses = project.getAllocationLandUses();
    for (final AllocationLU allocationLU : allocationLandUses) {
      if (allocationLU.getLabel() == null) {
        LOGGER.warn("Not performing analysis for null label for LU: {}", allocationLU.getId());
        continue;
      }
      for (final Projection projection : projectedSet) {
        LOGGER.info("getAreaByLU for: {}, id {}", allocationLU.getLabel(), allocationLU.getId());
        final String allocationFFName =
            allocationConfig.getAllocationColumnsMap().get(projection.getLabel());

        final Double areaByLU =
            geodataFinder.getAreaByLU(
                project.getSuitabilityConfig().getUnifiedAreaZone(),
                project.getAreaLabel(),
                project.getExistingLUAttributeName(),
                allocationLU.getFeatureFieldName(),
                allocationFFName,
                allocationLU.getAllocationFeatureFieldName());
        final AreaRequirement ar = new AreaRequirement();
        ar.setAllocationLU(allocationLU);
        ar.setRequiredArea(areaByLU);
        ar.setProjection(projection);
        allocationAnalysisReport.getLandUseInformation().add(ar);
      }
    }
    // Getting population and employment information
    LOGGER.info("Getting population and employment information: {}");
    final DemographicTrend demographicTrend =
        demandConfig.getTrendByLabel(
            allocationScenario.getDemandScenario().getDemographicTrendLabel());
    final Set<DemographicData> demographicData = demographicTrend.getDemographicData();
    for (final DemographicData data : demographicData) {
      if (data instanceof ResidentialDemographicData) {
        allocationAnalysisReport.getPopulationInformation().add((ResidentialDemographicData) data);
      } else if (data instanceof EmploymentDemographicData) {
        allocationAnalysisReport.getEmploymentInformation().add((EmploymentDemographicData) data);
      }
    }
    LOGGER.info(
        "Finished allocationAnalysisReport for: {}", allocationAnalysisReport.getProjectId());
    return allocationAnalysisReport;
  }
  public AllocationSimpleAnalysisReport getAllocationSimpleAnalysisReport(
      final AllocationScenario allocationScenario)
      throws WifInvalidInputException, WifInvalidConfigException, ParsingException {
    LOGGER.info("getAllocationSimpleAnalysisReport for: {}", allocationScenario.getLabel());
    final AllocationSimpleAnalysisReport allocationSimpleAnalysisReport =
        new AllocationSimpleAnalysisReport();

    // final WifProject project = allocationScenario.getWifProject();

    final String projectId = allocationScenario.getProjectId();
    final WifProject project = projectService.getProject(projectId);

    final String AllocationConfigsId = project.getAllocationConfigsId();

    final AllocationConfigs allocationConfig =
        AllocationConfigsDao.findAllocationConfigsById(AllocationConfigsId);

    allocationSimpleAnalysisReport.setReportType(allocationScenario.getDocType());
    allocationSimpleAnalysisReport.setLabel(project.getName());
    allocationSimpleAnalysisReport.setScenarioLabel(allocationScenario.getDocType());
    allocationSimpleAnalysisReport.setProjectId(allocationScenario.getProjectId());

    final Set<AllocationSimpleItemReport> setallocationSimpleItemReport =
        new HashSet<AllocationSimpleItemReport>();

    // Getting land use information
    // LOGGER.info("Getting land use information: {}");
    final DemandConfig demandConfig = demandConfigService.getDemandConfig(projectId);
    // LOGGER.info("Associated manualdemandConfigId: {}",
    // manualdemandConfig.getId());
    final TreeSet<Projection> projections = new TreeSet<Projection>(new YearComparator());
    projections.addAll(demandConfig.getProjections());
    final Projection current = projections.first();
    LOGGER.debug("current year projection: {}", current.getLabel());
    // setting up taking into account current projection year is not a
    // projection by itself,per se,
    // NavigableSet<Projection> projectedSet = projections.tailSet(
    // projections.first(), false);
    final Set<AllocationLU> allocationLandUses = project.getAllocationLandUses();
    for (final AllocationLU allocationLU : allocationLandUses) {
      if (allocationLU.getLabel() == null) {
        LOGGER.warn("Not performing analysis for null label for LU: {}", allocationLU.getId());
        continue;
      }
      for (final Projection projection : projections) {
        LOGGER.debug("getAreaByLU for: {}, id {}", allocationLU.getLabel(), allocationLU.getId());
        final String allocationFFName =
            allocationConfig.getAllocationColumnsMap().get(projection.getLabel());

        final Double areaByLU =
            geodataFinder.getAreaByLUNew(
                project.getSuitabilityConfig().getUnifiedAreaZone(),
                project.getAreaLabel(),
                allocationFFName,
                WifKeys.FUTURELU_PREFIX + allocationLU.getFeatureFieldName());

        final AllocationSimpleItemReport allocationSimpleItemReport =
            new AllocationSimpleItemReport();
        allocationSimpleItemReport.setLanduseName(allocationLU.getLabel());
        if (areaByLU == null) {
          allocationSimpleItemReport.setSumofArea(0.0);
        } else {
          allocationSimpleItemReport.setSumofArea(areaByLU);
        }

        allocationSimpleItemReport.setYear(projection.getYear());

        setallocationSimpleItemReport.add(allocationSimpleItemReport);
      }
    }
    allocationSimpleAnalysisReport.setAllocationSimpleItemReport(setallocationSimpleItemReport);
    LOGGER.info(
        "Finished allocationAnalysisReport for: {}", allocationSimpleAnalysisReport.getProjectId());
    return allocationSimpleAnalysisReport;
  }