module Devops
  module Model
    class ServerCategoryProviderAws < CategoryCloudProvider

      include ActiveModel::Validations

      attr_accessor :vpc_id, :subnet

      validate :validate_cloud_params

      def initialize d={}
        super(d)
        self.vpc_id = d["vpc_id"]
        self.subnet = d["subnet"]
      end

      def to_hash
        h = super
        h.merge!({
          "vpc_id" => self.vpc_id,
          "subnet" => self.subnet
        })
      end

      def account_instance
        @account_instance ||= Devops::Model::AwsProviderAccount.find(self.account)
      end

      # Creates server in aws
      def create_server(server, out)
        provider_instance.create_server(server, self.image, self.flavor, self.subnet, self.vpc_id, self.security_groups, out)
      end

    private
      def validate_cloud_params
        validate_provider_params
        if stack_template.nil? and flavor.nil? and image.nil? and security_groups.nil? and vpc_id.nil? and subnet.nil?
          errors.add(:aws_provider, 'You must define stack_template and/or all of the flavor, image, security_groups, vpc_id, subnet')
          return
        end
        provider_inst = provider_instance
        unless stack_template.nil?
          #TODO: validate
          errors.add(:stack_template, 'TODO')
        end
        unless flavor.nil? and image.nil? and security_groups.nil? and vpc_id.nil? and subnet.nil?
          validate_flavor
          validate_image

          if vpc_id.nil?
            errors.add(:vpc_id, "'vpc_id' is udefined")
          else

            if provider_inst.describe_vpcs({"vpc-id" => vpc_id}).empty?
              errors.add(:vpc_id, "'vpc_id' is invalid")
            else

              if subnet.nil?
                errors.add(:subnet, "'subnet' is invalid")
              else
                if provider_inst.networks({"vpc-id" => vpc_id, "subnet-id" => subnet}).empty?
                  errors.add(:subnet, "'subnet' is invalid")
                end
              end

              if security_groups.nil?
                errors.add(:security_groups, "'security_groups' is udefined")
              elsif !security_groups.is_a?(Array)
                errors.add(:security_groups, "'security_groups' is not an array")
              else
                invalid_sg = security_groups - provider_instance.security_groups({"vpc-id" => vpc_id }).keys
                errors.add(:security_groups, "Invalid security groups: '#{invalid_sg.join("', '")}'") if invalid_sg.empty?
              end
            end
          end

        end
      end

    end
  end
end

