require 'csv'
require 'date'
require 'yaml'

require 'aws-sdk-s3'

aws_configs = YAML.load(File.read( File.join(File.dirname(__FILE__),'config.yml')))
node_name = ARGV[2]

domains = {
  'avl.theorchard' => 'Asheville',
  'ec2.internal' => 'AWS',
  'theorchard.local' => 'New York',
}

# AVL and NY server networks
networks = {
  '10.10.20.' => '10.10.20.0/24',
  '10.10.4' => '10.10.40.0/22',
  '10.10.141.' => '10.10.141.0/29',
  '10.10.60.' => '10.10.60.0/24',
  '10.10.61.' => '10.10.61.0/29',
  '10.10.7' => '10.10.70.0/23',
  '10.10.8' => '10.10.80.0/22',
  '10.20.' => '10.20.0.0/22',
  '10.40.' => '10.40.0.0/22',
  '10.80.' => '10.80.0.0/24',
  '10.131.0.' => '10.131.0.0/29',
  '10.141.0.' => '10.141.0.0/29',
  '10.160.0.' => '10.160.0.0/24',
  '10.161.0.' => '10.161.0.0/29',
  '192.168.31.' => '192.168.31.0/24',
  '10.100.0.' => '10.100.0.0/24',
  '10.100.2.' => '10.100.2.0/23',
  '10.100.3.' => '10.100.2.0/23',
  '10.100.4.' => '10.100.4.0/24',
  '10.100.12.' => '10.100.12.0/23',
  '10.100.30.' => '10.100.30.0/24',
  '10.100.31.' => '10.100.31.0/24',
  '10.100.32.' => '10.100.32.0/24',
  '10.100.33.' => '10.100.33.0/24',
}

public_networks = %w(
  10.10.80.0/22
  10.100.0.0/24
  10.100.4.0/24
)

ignore_roles = %w(
  qa_base_linux
  prod_base_linux
  prod_base_windows
)

# Pull down the spreadsheet
s3 = Aws::S3::Client.new(region: aws_configs['aws_region'], signature_version: 'v4')
response = s3.get_object(
  response_target: aws_configs['local_file_path'],
  bucket: aws_configs['s3_bucket'],
  key: aws_configs['s3_object_path'])

puts "File downloaded, and was last modified at #{response['last_modified']}"

search(:node, "name:#{node_name}") do |node|
  ip_address = node['ipaddress']
  if node['virtualization']['system']
    vendor = node['virtualization']['system']
    model = node['virtualization']['system'] + ' ' + node['virtualization']['role']
  else
    vendor = node['kernel']['cs_info']['manufacturer']
    model = node['kernel']['cs_info']['model']
  end
  time_zone = node['time']['timezone']
  physical_location = domains[node['domain'].downcase]
  operating_system = if node['kernel']['name'] == 'Linux'
                       node['lsb']['description']
                     else
                       node['kernel']['name']
                     end
  network_zone = ''
  networks.each do |k, v|
    ip_address.start_with?(k) && network_zone = v
  end

  perimeter_zone = if public_networks.include?(network_zone)
                     'Yes'
                   else
                     'No'
                   end

  date_added = Date.today.to_s

  # Array of spreadsheet rows
  csv_row = [
    node_name,
    ip_address,
    vendor,
    time_zone,
    physical_location,
    perimeter_zone,
    operating_system,
    node.run_list,
    model,
    network_zone,
    date_added,
  ]

  # Check to see if host is already in sheet.
  csv = CSV.table(aws_configs['local_file_path'])
  if csv[:hostname].include?(node_name)
    puts "Host is already in spreadsheet. Please reconcile manually."
    exit
  end

  puts "Node data is as follows: #{csv_row}"

  CSV.open(aws_configs['local_file_path'], 'ab') do |csv|
    csv << csv_row
  end

  File.open(aws_configs['local_file_path'], 'r') do |file|
    new_object = s3.put_object(
      body: file,
      bucket: aws_configs['s3_bucket'],
      key: aws_configs['s3_object_path'],
      server_side_encryption: 'aws:kms',
      ssekms_key_id: aws_configs['kms_key_id']
    )

    puts "Spreadsheet uploaded to S3. New object version id is #{new_object['version_id']}"
  end
end

# Add this explicitly, lest knife try to exec the ARGS as additional scripts
exit 0
