text: # Copyright 2021 (c) Crown Copyright, GC.
  #
  # Licensed under the Apache License, Version 2.0 (the "License");
  # you may not use this file except in compliance with the License.
  # You may obtain a copy of the License at
  #
  #     http://www.apache.org/licenses/LICENSE-2.0
  #
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  
  """
  Carbon tax for each carbon_tax zone
  """
  
  import csv
  import os.path
  
  from pyomo.environ import Set, Param, NonNegativeReals
  
  
  def add_model_components(m, d, scenario_directory, subproblem, stage):
      """
  
      :param m:
      :param d:
      :return:
      """
  
      m.CARBON_TAX_ZONE_PERIODS_WITH_CARBON_TAX = \
          Set(dimen=2, within=m.CARBON_TAX_ZONES * m.PERIODS)
      m.carbon_tax = Param(
          m.CARBON_TAX_ZONE_PERIODS_WITH_CARBON_TAX,
          within=NonNegativeReals)
  
  
  def load_model_data(m, d, data_portal, scenario_directory, subproblem, stage):
      """
  
      :param m:
      :param d:
      :param data_portal:
      :param scenario_directory:
      :param subproblem:
      :param stage:
      :return:
      """
      data_portal.load(filename=os.path.join(scenario_directory, str(subproblem), str(stage),
                                             "inputs", "carbon_tax.tab"),
                       index=m.CARBON_TAX_ZONE_PERIODS_WITH_CARBON_TAX,
                       param=m.carbon_tax,
                       select=("carbon_tax_zone", "period",
                               "carbon_tax")
                       )
  
  
  def get_inputs_from_database(scenario_id, subscenarios, subproblem, stage, conn):
      """
      :param subscenarios: SubScenarios object with all subscenario info
      :param subproblem:
      :param stage:
      :param conn: database connection
      :return:
      """
      subproblem = 1 if subproblem == "" else subproblem
      stage = 1 if stage == "" else stage
      c = conn.cursor()
      carbon_tax = c.execute(
          """SELECT carbon_tax_zone, period, carbon_tax
          FROM inputs_system_carbon_tax
          JOIN
          (SELECT period
          FROM inputs_temporal_periods
          WHERE temporal_scenario_id = {}) as relevant_periods
          USING (period)
          JOIN
          (SELECT carbon_tax_zone
          FROM inputs_geography_carbon_tax_zones
          WHERE carbon_tax_zone_scenario_id = {}) as relevant_zones
          using (carbon_tax_zone)
          WHERE carbon_tax_scenario_id = {}
          AND subproblem_id = {}
          AND stage_id = {};
          """.format(
              subscenarios.TEMPORAL_SCENARIO_ID,
              subscenarios.CARBON_TAX_ZONE_SCENARIO_ID,
              subscenarios.CARBON_TAX_SCENARIO_ID,
              subproblem,
              stage
          )
      )
  
      return carbon_tax
  
  
  def validate_inputs(scenario_id, subscenarios, subproblem, stage, conn):
      """
      Get inputs from database and validate the inputs
      :param subscenarios: SubScenarios object with all subscenario info
      :param subproblem:
      :param stage:
      :param conn: database connection
      :return:
      """
      pass
      # Validation to be added
      # carbon_tax = get_inputs_from_database(
      #     scenario_id, subscenarios, subproblem, stage, conn)
  
  
  def write_model_inputs(scenario_directory, scenario_id, subscenarios, subproblem, stage, conn):
      """
      Get inputs from database and write out the model input
      carbon_tax.tab file.
      :param scenario_directory: string, the scenario directory
      :param subscenarios: SubScenarios object with all subscenario info
      :param subproblem:
      :param stage:
      :param conn: database connection
      :return:
      """
  
      carbon_tax = get_inputs_from_database(
          scenario_id, subscenarios, subproblem, stage, conn)
  
      with open(os.path.join(scenario_directory, str(subproblem), str(stage), "inputs",
                             "carbon_tax.tab"), "w", newline="") as \
              carbon_tax_file:
          writer = csv.writer(carbon_tax_file, delimiter="\t", lineterminator="\n")
  
          # Write header
          writer.writerow(
              ["carbon_tax_zone", "period", "carbon_tax"]
          )
  
          for row in carbon_tax:
              writer.writerow(row)
  