module Fog
  module Compute
    class XenServer
      class Real
        def get_vm_by_name(label)
          Fog::Logger.deprecation(
              'This method is deprecated. Use #get_by_name instead.'
          )
          @connection.request({:parser => Fog::Parsers::XenServer::Base.new, :method => 'VM.get_by_name_label' }, label)
        end

        def get_vm_by_uuid(uuid)
          Fog::Logger.deprecation(
              'This method is deprecated. Use #get_by_uuid instead.'
          )
          @connection.request({:parser => Fog::Parsers::XenServer::Base.new, :method => 'VM.get_by_uuid' }, uuid)
        end

        def create_server_raw(config = {})
          Fog::Logger.deprecation(
              'This method is deprecated. To create a server from scratch, use #create_server.'
          )

          config[:name_label] = config[:name] if config[:name]
          config.delete :name
          config[:affinity] = config[:__affinity] if config[:__affinity]
          config.delete :__affinity
          raise ArgumentError.new("Invalid :name_label attribute") \
            if !config[:name_label]
          raise ArgumentError.new("Invalid :affinity attribute") \
            if not config[:affinity]
          config[:affinity] = config[:affinity].reference \
            if config[:affinity].kind_of? Fog::Compute::XenServer::Host
          config.reduce({}){|memo,(k,v)| memo[k.to_sym] = v; memo}
          %w{ VCPUs_at_startup
              VCPUs_max
              VCPUs_params
              PV_bootloader_args
              PV_bootloader
              PV_kernel
              PV_ramdisk
              PV_legacy_args
              HVM_boot_policy
              HVM_boot_params
          }.each do |k|
            if config[k.downcase.to_sym]
              config[k.to_sym] = config[k.downcase.to_sym]
              config.delete k.downcase.to_sym
            end
          end
          vm_record = {
              :name_label =>              '',
              :name_description =>        'description',
              :user_version =>            '0',
              :affinity =>                '',
              :is_a_template =>           true,
              :auto_power_on =>           false,
              :memory_static_max =>       '536870912',
              :memory_static_min =>       '536870912',
              :memory_dynamic_max =>      '536870912',
              :memory_dynamic_min =>      '536870912',
              :VCPUs_params =>            {},
              :VCPUs_max =>               '1',
              :VCPUs_at_startup =>        '1',
              :actions_after_shutdown =>  'Destroy',
              :actions_after_reboot =>    'Restart',
              :actions_after_crash =>     'Restart',
              :platform =>                { :'nx' => 'true', :'acpi' => 'true', :'apic' => 'true', :'pae' => 'true', :'viridian' => 'true' },
              :other_config =>            {},
              :pool_name =>               '',
              :PV_bootloader =>           'pygrub', #pvgrub, eliloader
              :PV_kernel =>                '',
              :PV_ramdisk =>              '',
              :PV_args =>                 '-- quiet console=hvc0',
              :PV_bootloader_args =>      '',
              :PV_legacy_args =>          '',
              :HVM_boot_policy =>         '',
              :HVM_boot_params =>         {},
              :PCI_bus =>                 '',
              :recommendations =>         '',
          }.merge config
          ref = @connection.request({:parser => Fog::Parsers::XenServer::Base.new, :method => 'VM.create' }, vm_record)
          ref
        end

        def create_server( name_label, template = nil, networks = [], extra_args = {})
          if name_label.is_a?(Hash)
            config = name_label.reject { |_k,v| v.nil? }
            ref = @connection.request({:parser => Fog::Parsers::XenServer::Base.new, :method => 'VM.create' }, config)
          else
            Fog::Logger.deprecation(
                'This api is deprecated. The only expected param is a hash with the attributes.' + "\n" +
                    'To create a server from a template, use #clone_server instead.'
            )

            if !networks.kind_of? Array
              raise "Invalid networks argument"
            end

            if template.kind_of? String
              template_string = template
              # try template by UUID
              template = servers.templates.find { |s| s.uuid == template_string }
              if template.nil?
                # Try with the template name just in case
                template = servers.get get_vm_by_name(template_string)
              end
            end

            if template.nil?
              raise "Invalid template"
            end

            raise "Template #{template_string} does not exist" if template.allowed_operations.nil?
            raise 'Clone Operation not Allowed' unless template.allowed_operations.include?('clone')

            # Clone the VM template
            ref = clone_server name_label, template.reference
            # Add additional NICs
            networks.each do |n|
              create_vif ref, n.reference
            end
            if !extra_args[:auto_start] == false
              @connection.request({:parser => Fog::Parsers::XenServer::Base.new, :method => 'VM.provision'}, ref)
              start_vm( ref )
            end
          end

          ref
        end
      end

      class Mock
        def create_server( name_label, template = nil, network = nil, extra_args = {})
          Fog::Mock.not_implemented
        end

        def create_server_raw(config = {})
          Fog::Mock.not_implemented
        end
      end
    end
  end
end
