FactoryGirl.define do
  long_form_headers  = 'username,private_type,private_data,realm_key,realm_value,host_address,service_port,service_name,service_protocol,status,access_level,last_attempted_at'
  short_form_headers = 'username,private_data'
  login_status       = Metasploit::Model::Login::Status::ALL.select {|x| x != Metasploit::Model::Login::Status::UNTRIED }.sample
  access_level       = ['Admin', 'Foo'].sample
  last_attempted_at  = Time.now - 10

  factory :metasploit_credential_core_importer,
          class: Metasploit::Credential::Importer::Core do
            origin { FactoryGirl.build :metasploit_credential_origin_import }
            input  { generate(:well_formed_csv_compliant_header) }
  end


  # Well-formed CSV
  # Has a compliant header as defined by Metasploit::Credential::Importer::Core
  # Contains 2 realms
  sequence :well_formed_csv_compliant_header do |n|
    csv_string =<<-eos
#{long_form_headers}
han_solo-#{n},#{Metasploit::Credential::Password.name},falcon_chief,#{Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN},Rebels,,,,,#{login_status},#{access_level},#{last_attempted_at}
princessl-#{n},#{Metasploit::Credential::Password.name},bagel_head,#{Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN},Rebels,,,,,#{login_status},#{access_level},#{last_attempted_at}
lord_vader-#{n},#{Metasploit::Credential::Password.name},evilisfun,#{Metasploit::Model::Realm::Key::ORACLE_SYSTEM_IDENTIFIER},dstar_admins,,,,,#{login_status},#{access_level},#{last_attempted_at}
    eos
    StringIO.new(csv_string)
  end

  # Well-formed CSV
  # Has a compliant header as defined by Metasploit::Credential::Importer::Core
  # Contains 2 logins
  sequence :well_formed_csv_compliant_header_with_service_info do |n|
    csv_string =<<-eos
#{long_form_headers}
han_solo-#{n},#{Metasploit::Credential::Password.name},falcon_chief,#{Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN},Rebels,10.0.1.1,1234,smb,tcp,#{login_status},#{access_level},#{last_attempted_at}
princessl-#{n},#{Metasploit::Credential::Password.name},bagel_head,#{Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN},Rebels,10.0.1.2,1234,smb,tcp,#{login_status},#{access_level},#{last_attempted_at}
lord_vader-#{n},#{Metasploit::Credential::Password.name},evilisfun,#{Metasploit::Model::Realm::Key::ORACLE_SYSTEM_IDENTIFIER},dstar_admins,#{login_status},#{access_level},#{last_attempted_at}
    eos
    StringIO.new(csv_string)
  end

  # Well-formed CSV
  # Has a compliant header as defined by Metasploit::Credential::Importer::Core
  # Contains no realm data
  sequence :well_formed_csv_compliant_header_no_realm do |n|
    csv_string =<<-eos
#{long_form_headers}
han_solo-#{n},#{Metasploit::Credential::Password.name},falcon_chief,,,,,,#{login_status},#{access_level},#{last_attempted_at},,,,,#{login_status},#{access_level},#{last_attempted_at}
princessl-#{n},#{Metasploit::Credential::Password.name},bagel_head,,,,,,#{login_status},#{access_level},#{last_attempted_at},,,,,#{login_status},#{access_level},#{last_attempted_at}
lord_vader-#{n},#{Metasploit::Credential::Password.name},evilisfun,,,,,,#{login_status},#{access_level},#{last_attempted_at},,,,,#{login_status},#{access_level},#{last_attempted_at}
    eos
    StringIO.new(csv_string)
  end

  # Well-formed CSV
  # Has a compliant header as defined by Metasploit::Credential::Importer::Core
  # Contains 2 logins
  # Contains core with a blank Public
  sequence :well_formed_csv_compliant_header_missing_public do |n|
    csv_string =<<-eos
#{long_form_headers}
,#{Metasploit::Credential::Password.name},falcon_chief,#{Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN},Rebels,,,,,#{login_status},#{access_level},#{last_attempted_at}
princessl-#{n},#{Metasploit::Credential::Password.name},bagel_head,#{Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN},Rebels,,,,,#{login_status},#{access_level},#{last_attempted_at}
lord_vader-#{n},#{Metasploit::Credential::Password.name},evilisfun,#{Metasploit::Model::Realm::Key::ORACLE_SYSTEM_IDENTIFIER},dstar_admins,,,,,#{login_status},#{access_level},#{last_attempted_at}
    eos
    StringIO.new(csv_string)
  end

  # Well-formed CSV
  # Has a compliant header as defined by Metasploit::Credential::Importer::Core
  # Contains 2 logins
  # Contains core with a blank Private
  sequence :well_formed_csv_compliant_header_missing_private do |n|
    csv_string =<<-eos
#{long_form_headers}
han_solo,,,#{Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN},Rebels
princessl-#{n},#{Metasploit::Credential::Password.name},bagel_head,#{Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN},Rebels
lord_vader-#{n},#{Metasploit::Credential::Password.name},evilisfun,#{Metasploit::Model::Realm::Key::ORACLE_SYSTEM_IDENTIFIER},dstar_admins
    eos
    StringIO.new(csv_string)
  end


  # Well-formed CSV
  # Conforms to "short" form, in which only username and private_data are specified in the file
  sequence :short_well_formed_csv do |n|
    csv_string =<<-eos
#{short_form_headers}
han_solo-#{n},falC0nBaws
princessl-#{n},bagelHead
    eos
    StringIO.new(csv_string)
  end

  # Well-formed CSV, non-compliant headers
  # Conforms to "short" form, in which only username and private_data are specified in the file
  sequence :short_well_formed_csv_non_compliant_header do |n|
    csv_string =<<-eos
bad,wrong
han_solo-#{n},falC0nBaws
princessl-#{n},bagelHead
    eos
    StringIO.new(csv_string)
  end

  sequence :well_formed_csv_non_compliant_header do |n|
    csv_string =<<-eos
notgood,noncompliant,badheader,morebadheader
han_solo-#{n},#{Metasploit::Credential::Password.name},falcon_chief, #{Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN},Rebels
princessl-#{n},#{Metasploit::Credential::Password.name},bagel_head,#{Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN},Rebels
    eos
    StringIO.new(csv_string)
  end

  # Odd number of quotes will throw CSV::MalformedCSVError
  sequence :malformed_csv do |n|
    csv_string =<<-eos
foo,{"""}
    eos
    StringIO.new(csv_string)
  end

  # We have a header row but nothing else
  sequence :empty_core_csv do |n|
    csv_string =<<-eos
#{long_form_headers}
    eos
    StringIO.new(csv_string)
  end
end
