#
# Copyright 2010, Opscode, Inc.
# 
# 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.
#

require 'sinatra/base'
require 'chef-rundeck/node'
require 'json'
require 'chef/environment'

module ChefRundeck
  class App < Sinatra::Base
  VERSION = '3.3.1'

  class << self
      attr_accessor :config_file
      attr_accessor :username
      attr_accessor :custom_attributes

      def configure
        Chef::Config.from_file(ChefRundeck::App.config_file)
        Chef::Log.level = Chef::Config[:log_level]

        get '/health' do
           content_type 'application/json'
           return ({"version" => VERSION,  "name" => "chef-rundeck-x"}).to_json 
        end

        get '/environment' do
          content_type 'application/json'
          return Chef::Environment.list.keys.to_json
        end

        get '/node' do
          format = params.fetch("format", "json")
          refresh = params.fetch("refresh", false)
          filters =  params.dup.delete_if { |k,_| ["refresh", "format", "upcase", "key"].include? k }

          nodes = ChefRundeck::Node.get_all(username: ChefRundeck::App.username, refresh: refresh, filters: filters)

          if format == "xml"
            content_type 'text/xml'
            erb :xml, :locals => { :nodes => nodes }
          elsif format == "json"
            content_type 'application/json'
            key = params.fetch("key", "name")
            upcase = params.fetch("upcase", false)
            allowed_keys = ["chef_environment", "name"].concat(ChefRundeck::App.custom_attributes.split(","))

            unless allowed_keys.include?(key)
              status 400
              return { "error" => "Invalid key: #{key}" }.to_json
            end

            status 200
            return nodes.map do |n|
              if upcase
                unless n[key].nil?
                  n[key].upcase
                end
              else
                n[key]
              end
            end.uniq.compact.to_json
          end
        end

        at_exit do
          %w{json xml}.each do |fmt|
            cache_file = "#{Dir.tmpdir}/chef-rundeck-default.#{fmt}"
            File.delete(cache_file) if File.exist?(cache_file)
          end
        end
      end
    end
  end
end
