module Dalmatian
  class Terraform
    def self.fmt(args = nil)
      Helper.run!("terraform fmt #{args}")
    end

    def self.init(upgrade: false)
      cmd = "terraform init"
      cmd << " -upgrade=true" if upgrade
      Helper.run!(cmd)
    end

    def self.validate(var_file: "", tfvars: {})
      cmd = tfvar_arg_string(tfvars)
      cmd << " terraform validate"
      cmd << " -var-file=#{var_file}" unless var_file.to_s.strip.empty?
      Helper.run!(cmd)
    end

    def self.plan(var_file: "", tfvars: {}, verbose: false)
      cmd = tfvar_arg_string(tfvars)
      cmd << " terraform plan"
      cmd << " -var-file=#{var_file}" unless var_file.to_s.strip.empty?
      Logger.debug(cmd) if verbose
      Helper.run!(cmd)
    end

    def self.apply(var_file: "", tfvars: {}, auto_approve: false, verbose: false)
      cmd = tfvar_arg_string(tfvars)
      cmd << " terraform apply"
      cmd << " -var-file=#{var_file}" unless var_file.to_s.strip.empty?
      cmd << " -auto-approve" if auto_approve
      Logger.debug(cmd) if verbose
      Helper.run!(cmd)
    end

    def self.destroy(var_file: "", tfvars: {}, verbose: false)
      cmd = tfvar_arg_string(tfvars)
      cmd << " terraform destroy"
      cmd << " -var-file=#{var_file}" unless var_file.to_s.strip.empty?
      Logger.debug(cmd) if verbose
      Helper.run!(cmd)
    end

    def self.tfvar_arg_string(tfvars)
      tfvars.map { |key, value|
        value = value.to_json.gsub(/"([^"]+)":/, '\1 =') if value.respond_to?(:each)
        "TF_VAR_#{key}='#{value}'"
      }.join(" ")
    end

    def self.ensure_presence_of_workspace(workspace_name)
      Logger.info("Creating #{workspace_name} workspace")
      Helper.run!("terraform workspace new #{workspace_name}")
    rescue Error
      Logger.info("Selecting #{workspace_name} workspace")
      Helper.run!("terraform workspace select #{workspace_name}")
    end

    def self.list_workspaces
      Dir.chdir(Infrastructure::BOOTSTRAP_PATH) do
        Helper.run!("terraform workspace list")
      end
    end
  end
end
