defmodule RlRepo.ClientHandler do
  require Logger

  @moduledoc """
  """

  def process_request(client_socket) do
    Logger.info("Processing client request.")

    client_socket
      |> read_request
      |> create_response()
      |> create_response_header()
      |> write_response(client_socket)
  end

  def read_request(client_socket) do
    Logger.info("Reading request.")
    {:ok, request} = :gen_tcp.recv(client_socket, 0)
    Logger.info("Request recieved.")
    request
  end

  def create_response(request) do
    # TODO: Split off the info I need from the request body and I guess pass it around also
    Logger.info("REQUEST BODY\n#{request}")

    Logger.info("Building response body.")


    a = String.split(request, "\n\r")
    [get_line | _rest] = a
    Logger.info "get-line #{get_line}"


    b = String.split(get_line, " ")
    [request_type | rest] = b
    Logger.info "REQ_TYPE #{request_type}"
    [path | _rest] = rest
    Logger.info("PATH #{path}")

    # Parse path
    split_path = String.split(path, "/", trim: true)
    split_path_length = length(split_path)

    # TODO: Handle routing here.
      case split_path_length do
        1 ->
          RlRepo.Router.parse_1_segment_path(split_path)
          |> RlRepo.Router.route_1(request_type)

        3 ->
          RlRepo.Router.parse_3_segment_path(split_path)
          |> RlRepo.Router.route_3(request_type)

        4 ->
          RlRepo.Router.parse_4_segment_path(split_path)
          |> RlRepo.Router.route_4(request_type)

        # Note: Error handling.
        _ ->
          RlRepo.Router.status_404()
      end
  end

  def create_return_code_string(return_code) do
    case return_code do
      200 -> "200 OK"
      404 -> "404 Not Found"
    end
  end

  def create_response_header(body) do
    {return_code, content_type, body} = body
    html_ver = "1.1"
"""
HTTP/#{html_ver} #{create_return_code_string(return_code)}\r
Content-Type: #{content_type}\r
Content-Length: #{byte_size(body)}\r
\r
#{body}
"""
  end

  def write_response(response, client_socket) do
    :ok = :gen_tcp.send(client_socket, response)

    # Logger.info("Response:\n\n#{response}")

    :gen_tcp.close(client_socket)
  end
end