require_relative "request_parser"

module Devops
  module API3
    module Parser
      class ServerParser < RequestParser

        def servers
          q = {}
          if @params.key?("reserved")
            q[:reserved] = true if @params["reserved"] == "true"
          end
          if @params.key?("provider")
            q[:provider] = @params["provider"]
          end
          q
        end

        def server
          @params[:key] || @params["key"]
        end

        # TODO: skip_rollback flag
        def create
          @body ||= create_object_from_json_body
          project_name = check_string(@body["project"], "Parameter 'project' must be a not empty string")
          env_name = check_string(@body["environment"], "Parameter 'environment' must be a not empty string")
          category = check_string(@body["category"], "Parameter 'category' must be a not empty string")
          server_name = check_string(@body["name"], "Parameter 'name' should be null or not empty string", true)
          without_bootstrap = @body["without_bootstrap"]
          force = @body["force"]
          raise InvalidRecord.new("Parameter 'without_bootstrap' should be a null or true") unless without_bootstrap.nil? or without_bootstrap == true
          raise InvalidRecord.new("Parameter 'force' should be a null or true") unless force.nil? or force == true
          groups = check_array(@body["groups"], "Parameter 'groups' should be null or not empty array of string", String, true)
          key_name = check_string(@body["ssh_key"], "Parameter 'key' should be null or not empty string", true)
          rl = check_array(@body["run_list"], "Parameter 'run_list' should be a not empty array of string", String, true, true)
          Validators::Helpers::RunList.new(rl).validate! unless rl.nil?
          @body
        end

        def bootstrap
          @body ||= create_object_from_json_body(Hash, true)
          check_string(@body["cm_name"], "Parameter 'cm_name' should be a not empty string", true)
          rl = check_array(@body["run_list"], "Parameter 'run_list' should be a not empty array of string", String, true)
          Validators::Helpers::RunList.new(rl).validate! unless rl.nil?
          t = check_string(@body["bootstrap_template"], "Parameter 'bootstrap_template' should be a not empty string", true)
          @body
        end

        def deploy
          r = create_object_from_json_body
          tags = check_array(r["tags"], "Parameter 'tags' should be an array of strings", String, true)
          build_number = check_string(r["build_number"], "Parameter 'build_number' should be a not empty string", true)
          rl = check_array(r["run_list"], "Parameter 'run_list' should be an array of string", String, true)
          Validators::Helpers::RunList.new(rl).validate! unless rl.nil?
          r
        end

        def delete_list
          body = create_object_from_json_body
          check_array(body["servers_ids"], "Parameter 'servers_ids' must be not empty array of string", String)
        end

        def add_server
          @body ||= create_object_from_json_body
          project = check_string(@body["project"], "Parameter 'project' must be a not empty string")
          env = check_string(@body["environment"], "Parameter 'environment' must be a not empty string")
          category = check_string(@body["category"], "Parameter 'category' must be a not empty string")
          remote_user = check_string(@body["remote_user"], "Parameter 'remote_user' must be a not empty string")
          private_ip = check_string(@body["private_ip"], "Parameter 'private_ip' must be a not empty string")
          public_ip = check_string(@body["public_ip"], "Parameter 'public_ip' should be a not empty string", true)
          rl = check_array(@body["run_list"], "Parameter 'run_list' should be a not empty array of string", String, true, true)
          Validators::Helpers::RunList.new(rl).validate! unless rl.nil?
          name = check_string(@body["name"], "Parameter 'name' should be a not empty string")
          server_attrs = {
            project: project,
            environment: env,
            category: category,
            name: name,
            remote_user: remote_user,
            private_ip: private_ip,
            public_ip: public_ip,
            run_list: rl,
            name: name
          }
        end

        def add_and_bootstrap_servers
          @body ||= create_object_from_json_body
          project = check_string(@body["project"], "Parameter 'project' must be a not empty string")
          deploy_env = check_string(@body["deploy_env"], "Parameter 'deploy_env' must be a not empty string")
          key = check_string(@body["key"], "Parameter 'key' must be a not empty string")
          remote_user = check_string(@body["remote_user"], "Parameter 'remote_user' must be a not empty string")
          rl = check_array(@body["run_list"], "Parameter 'run_list' should be a not empty array of string", String, true, true)
          check_string(@body["bootstrap_template"], "Parameter 'bootstrap_template' should be a not empty string", true)
          Validators::Helpers::RunList.new(rl).validate! unless rl.nil?

          ips_with_names = parse_list_of_ips_with_names(@body['ips_with_names'])
          servers_attrs = ips_with_names.map do |ip, chef_node_name|
            {
              project: project,
              deploy_env: deploy_env,
              key: key,
              remote_user: remote_user,
              private_ip: ip,
              chef_node_name: chef_node_name,
              run_list: rl
            }
          end
          servers_attrs[:public_ip] = @body['public_ip'] if @body['public_ip']
          [@body, servers_attrs]
        end

        def tags
          @body ||= create_object_from_json_body
          check_param(@body["tags"], Hash, "Parameter 'tags' should be a hash", false, true)
        end

        def run_list
          @body ||= create_object_from_json_body
          rl = check_array(@body["run_list"], "Parameter 'run_list' should be a not empty array of string", String, false, true)
          Validators::Helpers::RunList.new(rl).validate!
          rl
        end

        def delete_list
          @body ||= create_object_from_json_body
          check_array(@body["servers_ids"], "Parameter 'servers_ids' should be a not empty array of string", String, false)
        end

        private

        def parse_list_of_ips_with_names(text)
          hash = {}
          text.each_line do |line|
            ip, name = line.split(':').map(&:strip)
            hash[ip] = name
          end
          hash
        end

      end
    end
  end
end
