require "fileutils"
require "commands/status"
require "app/api3/parsers/script"
require "lib/ssh/ssh_utils"
require_relative "request_handler"

module Devops
  module API3
    module Handler
      class Script < RequestHandler

        set_parser Devops::API3::Parser::ScriptParser

        def scripts
          res = []
          Dir.foreach(DevopsConfig.config[:scripts_dir]) {|f| res.push(f) unless f.start_with?(".")}
        end

        def execute_command out, server_id
          cmd = parse.body
          s = begin
            Devops::Model::Server.find(server_id)
          rescue Mongoid::Errors::DocumentNotFound
            raise Devops::Exception::RecordNotFound.new("Server '#{id}' not found")
          end
          Devops::Model::Project.check_user_authorization(s.project, s.environment, parser.current_user)
          cert = begin
            Devops::Model::Key.find(s.ssh_key)
          rescue Mongoid::Errors::DocumentNotFound
            raise Devops::Exception::RecordNotFound.new("SSH key '#{s.ssh_key}' not found")
          end
          Devops::SSH::Utils.run_command_out(cmd, s.public_ip || s.private_ip, s.remote_user, cert.path, out)
        end

        def run_script out, script_name
          nodes, script_params = parser.run_script
          file = File.join(DevopsConfig.config[:scripts_dir], script_name)
          unless File.exists?(file)
            out << "File '#{script_name}' does not exist\n"
            return
          end
          servers = ::Devops::Model::Server.where('id.in' => nodes)
          if servers.empty?
            out << "No servers found for ids '#{nodes.join("', '")}'\n"
            return
          end
          user = parser.current_user
          servers.each do |s|
            Devops::Model::Project.check_user_authorization(s.project, s.environment, user)
          end
          status = []
          servers.each do |s|
            cert = begin
              Devops::Model::Key.find(s.ssh_key)
            rescue Mongoid::Errors::DocumentNotFound
              out.puts "No SSH key found for '#{s.id}'"
              out.flush
              status.push 2
              next
            end
            out.puts "\nRun script on '#{s.id}'"
            status.push(Devops::SSH::Utils.run_script(file, s.public_ip || s.private_ip, s.remote_user, cert.path, out))
          end
          status
        end

        def create_script file_name
          file = File.join(DevopsConfig.config[:scripts_dir], file_name)
          raise Devops::Exception::ConflictError.new("File '#{file_name}' already exist") if File.exists?(file)
          File.open(file, "w") {|f| f.write(parser.body)}
        end

        def delete_script file_name
          file = File.join(DevopsConfig.config[:scripts_dir], file_name)
          raise Devops::Exception::RecordNotFound.new("File '#{file_name}' does not exist") unless File.exists?(file)
          FileUtils.rm(file)
        end

      end
    end
  end
end

