require 'socket'
require './http.rb'
require 'time'

class FakeTunnelConnector
  attr_accessor :port, :server, :ssl_context

  CRLF = "\r\n".freeze

  def initialize(port, ssl_context = nil)
    @port = port
    @server = TCPServer.open(port)
    @ssl_context = ssl_context
  end

  def listen_and_respond
    if ssl_context
      tls_server = ssl_server
      tcp_socket = tls_server.accept
    else
      tcp_socket = server.accept
    end
    response = read_socket(tcp_socket)
    location = response[:start_line][:location]
    write_response(tcp_socket, location)
    close_connection(tcp_socket)
  end

  def ssl_server
    OpenSSL::SSL::SSLServer.new server, ssl_context if ssl_context
  end

  def read_socket(tcp_socket)
    start_line = []
    headers = []
    puts 'Request Incoming:'
    puts '-------------------'
    # read lines from socket
    while (line = tcp_socket.gets) && (line.chomp.length > 0)
      # check for a valid http verb sent
      start_line = parse_http_start_request_line(line) if Http::METHODS.include?(line.split.first)
      header_line = parse_http_header_request_line(line)
      headers << header_line unless header_line.nil?
    end
    puts start_line
    puts 'Request Headers:'
    puts '-------------------'
    puts headers
    puts CRLF
    { start_line: start_line, headers: headers }
  end

  def parse_http_start_request_line(line)
    split_request = line.split
    verb = split_request.first
    location = split_request.select { |l| l if l.start_with?('/') }.first
    protocol = split_request.last
    {
      verb: verb,
      location: location,
      protocol: protocol
    }
  end

  def parse_http_header_request_line(line)
    if line.split.first.end_with?(':')
      split_request = line.split(':')
      key = split_request[0]
      value = if split_request.count >= 3
                split_request[1] + ':' + split_request[2]
              else
                split_request[1]
              end
      Hash[key, value]
    end
  end

  def write_response(tcp_socket, location)
    routed_response_string = route_request(location)
    body = ok(routed_response_string)
    tcp_socket.puts(ok_headers)
    tcp_socket.puts(body)
  end

  def close_connection(tcp_socket)
    tcp_socket.close
  end

  def ok(body = 'Success')
    body
  end

  def ok_headers
    "HTTP/1.1 200 OK#{CRLF}" +
      "Date: #{Time.now.utc}#{CRLF}" +
     CRLF 
  end

  def route_request(location)
    if location == '/scans'
      scans
    elsif location == '/session'
      login
    else
      ok
    end
  end

  def scans
    body = '{
      "folders":[
        {"unread_count":0,"custom":0,"default_tag":0,"type":"trash","name":"Trash","id":821},
        {"unread_count":4,"custom":0,"default_tag":1,"type":"main","name":"My Scans","id":822}
      ],
      "scans":[
        {"id":851, "name":"Virtual Tunnel Scan File 1",    "folder_id":822,"type":"local","read":false,"last_modification_date":1487137935,"creation_date":1487137921,"status":"completed","uuid":"5afd0023-977a-9124-2638-f14d0958677672812a5da3529d5f","shared":false,"user_permissions":128,"owner":"bmcdevitt","timezone":"Zulu","rrules":"FREQ=ONETIME","starttime":"20170202T160000","enabled":true,"control":true},
        {"id":889, "name":"Virtual Tunnel Scan File 2", "folder_id":822,"type":"local","read":false,"last_modification_date":1487017337,"creation_date":1487017329,"status":"completed","uuid":"0efb416d-bf92-92a6-ec3b-fb309c0a100d9cc9c3d05cb8d15c","shared":false,"user_permissions":128,"owner":"bmcdevitt","timezone":null,"rrules":null,"starttime":null,"enabled":true,"control":true},
        {"id":832, "name":"Virtual Tunnel Scan File 3",  "folder_id":822,"type":"local","read":false,"last_modification_date":1486158311,"creation_date":1486156633,"status":"completed","uuid":"e96a9447-c500-a02c-b321-aaa54243ea83668c7d3bec760ead","shared":false,"user_permissions":128,"owner":"bmcdevitt","timezone":null,"rrules":null,"starttime":null,"enabled":true,"control":true},
        {"id":834, "name":"Virtual Tunnel Scan File 4",         "folder_id":822,"type":"local","read":false,"last_modification_date":1486156549,"creation_date":1486156540,"status":"completed","uuid":"fe3c45b9-e17c-748f-85e2-f6529e7c997fcc048b683781b8fc","shared":false,"user_permissions":128,"owner":"bmcdevitt","timezone":null,"rrules":null,"starttime":null,"enabled":true,"control":true},
        {"id":835, "name":"Virtual Tunnel Scan File 5",         "folder_id":822,"type":"local","read":false,"last_modification_date":1486156549,"creation_date":1486156540,"status":"completed","uuid":"f4170000-e17c-748f-85e2-f6529e7c997fcc048b683781b8fc","shared":false,"user_permissions":128,"owner":"bmcdevitt","timezone":null,"rrules":null,"starttime":null,"enabled":true,"control":true},
        {"id":823, "name":"Virtual Tunnel Scan File 6",            "folder_id":821,"type":"local","read":true,"last_modification_date":1480977444,"creation_date":1480977430,"status":"completed","uuid":"bf1d0958-5a67-f413-dffd-35131927f5084ad38817344c69ef","shared":false,"user_permissions":128,"owner":"bmcdevitt","timezone":null,"rrules":null,"starttime":null,"enabled":false,"control":true},
        {"id":826, "name":"Virtual Tunnel Scan File 7",                     "folder_id":821,"type":"local","read":true,"last_modification_date":1480976737,"creation_date":1480974579,"status":"completed","uuid":"60f7f497-4f3b-e3a8-6364-72a6f763d20b2da84f89010c7883","shared":false,"user_permissions":128,"owner":"bmcdevitt","timezone":null,"rrules":null,"starttime":null,"enabled":false,"control":true},
        {"id":873, "name":"Virtual Tunnel Scan File 8",             "folder_id":821,"type":null,"read":true,"last_modification_date":0,"creation_date":0,"status":"empty","uuid":null,"shared":false,"user_permissions":128,"owner":"bmcdevitt","timezone":null,"rrules":null,"starttime":null,"enabled":false,"control":true}
      ],
      "timestamp":1487197426}'
    ok(body)
  end

  def login
    body = '{"token":"3b51619a125d90cd0778bd4c02cd7be34de6dc9268eecd25"}'
    ok(body)
  end
end