#!/usr/bin/env ruby
#
require "erb"
require "yaml"
require "ostruct"
require "fileutils"
require "./templates/fixtures/fixture_formatter"
require "./templates/generators/path_scenarios_generator.rb"

class Generator < OpenStruct

  CONFIG = "params.yml"
  TESTS_CONFIG = "features/support/config.yml"

  include PathScenariosGenerator

  def initialize
    config_file = ENV["DEVOPS_FEATURES_GENERATOR_CONFIG"] || ENV["CONFIG"] || CONFIG
    @config = YAML.load_file(File.new(config_file))
    load_fixtures()
    super(:config => @config, :formatter => @formatter, :fixtures => @fixtures)
  end

  def configure!
    c = {}
    %w{host port username password path_prefix username_without_privileges password_without_privileges}.each do |key|
      c[key] = @config[key]
    end
    File.open(TESTS_CONFIG, "w") {|f| f.write(c.to_yaml) }
    self
  end

  def generate!(templates)
    templates.each do |input, output|
      puts "Input: #{input}"
      if File.exists?(input)
        begin
          file_data = File.read(input)
          if file_data.nil?
            puts "Data of file '#{input}' is nil"
          else
            data = render(file_data)
            dir = File.dirname(output)
            FileUtils.mkdir_p(dir) unless File.exists?(dir)
            File.open(output, "w") {|f| f.write(data)}
          end
        rescue => e
          puts "\tError: #{e.message}"
        end
      else
        puts "WARN: file '#{input}' does not exist"
      end
    end
  end


  def self.clean!
    dir = "features/api_v3/"
    if File.exists?(dir)
      puts "Removing directory '#{dir}'"
      FileUtils.rm_r(dir)
    end

=begin
    feature_files.each do |feature_file|
      if File.exists?(feature_file)
        FileUtils.rm_f(feature_file)
      else
        puts "WARN: file '#{feature_file}' does not exist"
      end
    end
=end
  end

  def concat(string)
    @output.concat(string)
  end

  private

  def render(template)
    @output = ""
    ERB.new(template, 0, "%<>", "@output").result(binding)
  end

  def load_fixtures
    puts "Load fixures:"
    @fixtures = {}
    Dir["templates/fixtures/*.yml"].each do |fixture_path|
      fixture_name = File.basename(fixture_path, '.yml')
      print "\t#{fixture_path}..."
      @fixtures[fixture_name] = YAML.load_file(fixture_path)
      puts " ok"
    end

    @formatter = FixtureFormatter.new(@fixtures)
  end
end

templates = {

  #prepare
  "templates/api_v3/00_prepare/00_create_role.feature.erb" => "features/api_v3/00_prepare/00_create_role.feature",
  "templates/api_v3/00_prepare/10_create_user.feature.erb" => "features/api_v3/00_prepare/10_create_user.feature",
  #list
  "templates/api_v3/01_list/00_chef.feature.erb" => "features/api_v3/01_list/00_chef.feature",
  "templates/api_v3/01_list/10_filter.feature.erb" => "features/api_v3/01_list/10_filter.feature",
  "templates/api_v3/01_list/10_key.feature.erb" => "features/api_v3/01_list/10_key.feature",
  "templates/api_v3/01_list/11_provider.feature.erb" => "features/api_v3/01_list/11_provider.feature",
  "templates/api_v3/01_list/10_user.feature.erb" => "features/api_v3/01_list/10_user.feature",
  "templates/api_v3/01_list/20_image.feature.erb" => "features/api_v3/01_list/20_image.feature",
  "templates/api_v3/01_list/30_project.feature.erb" => "features/api_v3/01_list/30_project.feature",

  #create
  "templates/api_v3/10_create/00_filter.feature.erb" => "features/api_v3/10_create/00_filter.feature",
  "templates/api_v3/10_create/00_key.feature.erb" => "features/api_v3/10_create/00_key.feature",
  "templates/api_v3/10_create/01_provider_account.feature.erb" => "features/api_v3/10_create/01_provider_account.feature",
  "templates/api_v3/10_create/10_image.feature.erb" => "features/api_v3/10_create/10_image.feature",
  "templates/api_v3/10_create/20_project.feature.erb" => "features/api_v3/10_create/20_project.feature",
  "templates/api_v3/10_create/21_deploy_env.feature.erb" => "features/api_v3/10_create/21_deploy_env.feature",
  "templates/api_v3/10_create/40_server.feature.erb" => "features/api_v3/10_create/40_server.feature",
=begin
  "templates/api_v3/10_create/00_stack_template.feature.erb" => "features/api_v3/10_create/00_stack_template.feature",
  "templates/api_v3/10_create/50_stack.feature.erb" => "features/api_v3/10_create/50_stack.feature",
  "templates/api_v3/10_create/30_script.feature.erb" => "features/api_v3/10_create/30_script.feature",
  "templates/api_v3/10_create/40_deploy_env.feature.erb" => "features/api_v3/10_create/40_deploy_env.feature",
  "templates/api_v3/10_create/00_user.feature.erb" => "features/api_v3/10_create/00_user.feature",
=end

  #update
  "templates/api_v3/20_update/10_image.feature.erb" => "features/api_v3/20_update/10_image.feature",
  "templates/api_v3/20_update/20_project.feature.erb" => "features/api_v3/20_update/20_project.feature",
=begin
  "templates/api_v3/20_update/00_user.feature.erb" => "features/api_v3/20_update/00_user.feature",
=end

  #delete
=begin
  "templates/api_v3/90_delete/00_stack_template.feature.erb" => "features/api_v3/90_delete/00_stack_template.feature",
  "templates/api_v3/90_delete/10_script.feature.erb" => "features/api_v3/90_delete/10_script.feature",
  "templates/api_v3/90_delete/10_stack.feature.erb" => "features/api_v3/90_delete/10_stack.feature",
  "templates/api_v3/90_delete/20_deploy_env.feature.erb" => "features/api_v3/90_delete/20_deploy_env.feature",
=end
  "templates/api_v3/90_delete/60_server.feature.erb" => "features/api_v3/90_delete/60_server.feature",
  "templates/api_v3/90_delete/80_project.feature.erb" => "features/api_v3/90_delete/80_project.feature",
  "templates/api_v3/90_delete/90_image.feature.erb" => "features/api_v3/90_delete/90_image.feature",
  "templates/api_v3/90_delete/98_key.feature.erb" => "features/api_v3/90_delete/98_key.feature",
  "templates/api_v3/90_delete/98_filter.feature.erb" => "features/api_v3/90_delete/98_filter.feature",
  "templates/api_v3/90_delete/99_finalize.feature.erb" => "features/api_v3/90_delete/99_finalize.feature"
}

if ARGV.first != 'clean'
  generator = Generator.new.configure!
  generator.generate!(templates)
else
  Generator.clean!
end

