commit 07d553ab9271dbc9caeb701959cd17e49a67eae2
Author: Able <abl3theabove@gmail.com>
Date:   Tue Feb 18 09:21:58 2025 -0600

    WEB: Implemented terrible routing control.

diff --git a/.formatter.exs b/.formatter.exs
new file mode 100644
index 0000000..d2cda26
--- /dev/null
+++ b/.formatter.exs
@@ -0,0 +1,4 @@
+# Used by "mix format"
+[
+  inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
+]
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..272a046
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,26 @@
+# The directory Mix will write compiled artifacts to.
+/_build/
+
+# If you run "mix test --cover", coverage assets end up here.
+/cover/
+
+# The directory Mix downloads your dependencies sources to.
+/deps/
+
+# Where third-party dependencies like ExDoc output generated docs.
+/doc/
+
+# Ignore .fetch files in case you like to edit your project deps locally.
+/.fetch
+
+# If the VM crashes, it generates a dump, let's ignore it too.
+erl_crash.dump
+
+# Also ignore archive artifacts (built via "mix archive.build").
+*.ez
+
+# Ignore package tarball (built via "mix hex.build").
+rl_repo-*.tar
+
+# Temporary files, for example, from tests.
+/tmp/
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..12e449b
--- /dev/null
+++ b/README.md
@@ -0,0 +1,36 @@
+# RlRepo
+
+## API Usage
+/<repo_name>/<?sub_repo_name>/<pkg_name>/download
+
+### Repo management
+/repo/<action>
+
+#### Repo Creation
+/repo/create
+
+
+#### Repo deletion
+/repo/delete
+
+### Sub-repo management
+/<repo_name>/create
+/<repo_name>/delete
+
+
+### Package management
+/<repo_name>/<action>
+
+#### Create
+/<repo_name>/create
+
+#### Delete
+/<repo_name>/delete
+
+
+
+### Package Info
+/<repo_name>/<pkg_name>/<action>
+
+
+
diff --git a/lib/client_handler.ex b/lib/client_handler.ex
new file mode 100644
index 0000000..00c4e89
--- /dev/null
+++ b/lib/client_handler.ex
@@ -0,0 +1,89 @@
+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
+    Logger.info("Building body.")
+
+    # NOTE: Reliability testing.
+    if String.match?(request, ~r{GET /error}) do
+      raise(request)
+    end
+
+    # TODO: Handle routing here.
+    a = String.split(request, "\n\r");
+    Logger.info a
+    [get_line | rest] = a
+
+    b = String.split(get_line, " ");
+    [request_type | rest] = b
+    [path | rest] = rest
+    Logger.info "#{request_type} #{path}"
+
+    # Parse path
+    split_path = String.split(path, "/");
+    # Ignore the first slash.
+    [_ | rest ] = split_path
+
+    split_path_length = length(rest)
+    Logger.info split_path_length
+
+    ret = case split_path_length do
+      3 ->
+        RlRepo.Router.parse_3_segment_path(rest)
+          |> RlRepo.Router.route_3(request_type)
+      4 ->
+        RlRepo.Router.parse_4_segment_path(rest)
+          |> RlRepo.Router.route_4(request_type)
+    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
+
+    """
+    HTTP/1.1 #{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
diff --git a/lib/json.ex b/lib/json.ex
new file mode 100644
index 0000000..1c93150
--- /dev/null
+++ b/lib/json.ex
@@ -0,0 +1,8 @@
+defmodule RlRepo.Json do
+  require Logger
+  @moduledoc """
+  """
+  def fmt_json(a) do
+    "{\"pkg_names\": 10}"
+  end
+end
diff --git a/lib/rl_repo.ex b/lib/rl_repo.ex
new file mode 100644
index 0000000..586ef09
--- /dev/null
+++ b/lib/rl_repo.ex
@@ -0,0 +1,31 @@
+defmodule RlRepo do
+  require Logger
+  @moduledoc """
+  """
+
+  @doc """
+  """
+  def start(port) do
+    {:ok, listener_socket} = :gen_tcp.listen(port, [:binary, packet: :raw, active: false, reuseaddr: true])
+
+    Logger.info("Listening on port #{port}")
+
+    loop_acceptor(listener_socket)
+  end
+
+
+  def loop_acceptor(listener_socket) do
+    Logger.debug "Waiting for connection."
+
+    {:ok, client_socket} = :gen_tcp.accept(listener_socket)
+
+    Logger.info "Client Connected."
+
+    process_pid = spawn(fn -> RlRepo.ClientHandler.process_request(client_socket) end)
+    Logger.info "Handling client connection at PID #{inspect(process_pid)}"
+    Logger.info "Handing over socket control."
+    :ok = :gen_tcp.controlling_process(client_socket, process_pid)
+
+    loop_acceptor(listener_socket)
+  end
+end
diff --git a/lib/rl_repo/application.ex b/lib/rl_repo/application.ex
new file mode 100644
index 0000000..a636e2b
--- /dev/null
+++ b/lib/rl_repo/application.ex
@@ -0,0 +1,23 @@
+defmodule RlRepo.Application do
+  # See https://hexdocs.pm/elixir/Application.html
+  # for more information on OTP Applications
+  @moduledoc false
+
+  use Application
+
+  @impl true
+  def start(_type, _args) do
+    port = String.to_integer(System.get_env("PORT") || "10002")
+
+    children = [
+      # Starts a worker by calling: RlRepo.Worker.start_link(arg)
+      # {RlRepo.Worker, arg}
+      Supervisor.child_spec({Task, fn -> RlRepo.start(port) end}, restart: :permanent)
+    ]
+
+    # See https://hexdocs.pm/elixir/Supervisor.html
+    # for other strategies and supported options
+    opts = [strategy: :one_for_one, name: RlRepo.Supervisor]
+    Supervisor.start_link(children, opts)
+  end
+end
diff --git a/lib/routing.ex b/lib/routing.ex
new file mode 100644
index 0000000..fab254d
--- /dev/null
+++ b/lib/routing.ex
@@ -0,0 +1,45 @@
+defmodule RlRepo.Router do
+  require Logger
+  @moduledoc """
+
+  """
+  def route_3( path, request_type) do
+    Logger.info "#{request_type}"
+    {repo_name, pkg_name, action} = path
+
+    if action == "info" do
+      Logger.info "fetching json"
+    end
+
+    {200, "application/json", "{\"pkg_name\": \"#{pkg_name}\"}"}
+  end
+
+  def route_4(path, request_type) do
+    Logger.info "#{request_type}"
+    {repo_name, sub_repo_name, pkg_name, action} = path
+    {200, "text/html", "<p>Hi</p>"}
+  end
+
+
+  def parse_3_segment_path(path) do
+    [repo_name | rest ] = path
+    [pkg_name | rest] = rest
+    [action | _ ] = rest
+
+    Logger.info "REPO #{repo_name} PKG #{pkg_name} ACTION #{action}"
+
+    {repo_name, pkg_name, action}
+  end
+
+
+  def parse_4_segment_path(path) do
+    [repo_name | rest ] = path
+    [sub_repo_name | rest] = rest
+    [pkg_name | rest] = rest
+    [action | _ ] = rest
+
+    Logger.info "REPO #{repo_name} SUB_REPO #{sub_repo_name} PKG #{pkg_name} ACTION #{action}"
+
+    {repo_name, sub_repo_name, pkg_name, action}
+  end
+end
diff --git a/mix.exs b/mix.exs
new file mode 100644
index 0000000..47b01ca
--- /dev/null
+++ b/mix.exs
@@ -0,0 +1,29 @@
+defmodule RlRepo.MixProject do
+  use Mix.Project
+
+  def project do
+    [
+      app: :rl_repo,
+      version: "0.1.0",
+      elixir: "~> 1.12",
+      start_permanent: Mix.env() == :prod,
+      deps: deps()
+    ]
+  end
+
+  # Run "mix help compile.app" to learn about applications.
+  def application do
+    [
+      extra_applications: [:logger],
+      mod: {RlRepo.Application, []}
+    ]
+  end
+
+  # Run "mix help deps" to learn about dependencies.
+  defp deps do
+    [
+      # {:dep_from_hexpm, "~> 0.3.0"},
+      # {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}
+    ]
+  end
+end
diff --git a/test/rl_repo_test.exs b/test/rl_repo_test.exs
new file mode 100644
index 0000000..fa599e3
--- /dev/null
+++ b/test/rl_repo_test.exs
@@ -0,0 +1,8 @@
+defmodule RlRepoTest do
+  use ExUnit.Case
+  doctest RlRepo
+
+  test "greets the world" do
+    # assert RlRepo.hello() == :world
+  end
+end
diff --git a/test/test_helper.exs b/test/test_helper.exs
new file mode 100644
index 0000000..869559e
--- /dev/null
+++ b/test/test_helper.exs
@@ -0,0 +1 @@
+ExUnit.start()