require 'erb'

class Hash

  def deep_merge!(second)
    second.each_pair do |k, v|
      if self[k].is_a?(Hash) and second[k].is_a?(Hash)
        self[k].deep_merge!(second[k])
      else
        self[k] = second[k]
      end
    end
  end
end

module BuildWise
  class Config
    def initialize(app_name = nil, cli_options = {})
      @config = HashWithIndifferentAccess.new

      if app_name
        merge!(YAML.load(ERB.new(IO.read(CONFIG_FILE)).result)) if test(?f, CONFIG_FILE)
        config_file_path = File.join(BUILDWISE_HOME, "config", "#{app_name.downcase}.yml")
        merge!(YAML.load(ERB.new(IO.read(config_file_path)).result))
      end
      merge!(cli_options)
    end

    def [](*path)
      c = @config
      path.each { |p|
        c = c[p]
        return if c.nil?
      }
      c
    end

    def merge!(hash, overwrite = true)
      return if hash.nil? || hash.empty?
      if overwrite
        @config.deep_merge!(hash)
      else
        d = HashWithIndifferentAccess.new(hash)

        d.deep_merge!(@config)
        @config = d
      end
    end

    def inspect
      @config.inspect
    end

    def overwrite(new_hash)
      @config = HashWithIndifferentAccess.new
      merge!(new_hash)
    end

    def save_back(app_name)
      new_content = @config.to_yaml
      new_content.gsub!("!map:ActiveSupport::HashWithIndifferentAccess", "")
      config_file_path = File.join(BUILDWISE_HOME, "config", "#{app_name.downcase}.yml")
      File.open(config_file_path, 'w') { |f| f.write(new_content) }
    end

    private
    def symbolize_hash(hash)
      hash.each_pair { |k, v|
        if v === Hash
          hash[k] = HashWithIndifferentAccess.new(symbolize_hash(v))
        end
      }
    end
  end
end