#!/bin/env fish
begin
    set -l dir (status dirname)
    set -l root /usr/local/lib
    set -l overrides "docker-compose.overrides.yml"
    set -l nginxRoot "/etc/nginx/conf.d"
    source "$dir/../../../../lib/software.fish"

    function getRandomPort
        random 49152 65535
    end

    function getPortPattern
        echo "^\([.[:digit:]]\+:\)\?\([[:digit:]]\+\)\(:[[:digit:]]\+\(\/tcp\|udp\)\?\)"
    end

    function __substitutePort -a substitution
        sed "s/$(getPortPattern)/$substitution/"
    end

    function extractPort
        __substitutePort "\2"
    end

    function mutatePort -a port
        __substitutePort "\1$port\3"
    end

    function getServiceName
        argparse -i "name=" -- $argv
        echo "$_flag_name"
    end

    function getMachineFQDN -V dir
        source "$dir/../../../../lib/settings.fish"
        getOSConfig fqdn
    end

    function getServiceRoot -V root
        echo "$root/$(getServiceName $argv)"
    end

    function getServiceKey -a name
        echo ".services.[$(echo "{}" | NAME="$name" jq "env.NAME")]"
    end

    function __getServiceNginxConfig -V nginxRoot
        echo "$nginxRoot/$(getServiceName $argv).conf"
    end

    function getServiceOverrides -V overrides
        echo "$(getServiceRoot $argv)/$overrides"
    end

    function getServicePortKey -V overrides -a name
        echo "$(getServiceKey "$name").ports[0]"
    end

    function getServiceDomain -a subdomain domain
        if [ -z "$domain" ]
            set domain (getMachineFQDN)
        end

        if [ -n "$subdomain" ]
            set domain "$subdomain.$domain"
        end

        echo "$domain"
    end

    function getExtraServerConfig -a domain
    end

    function getServiceLocationConfig -a domain service location
        getServiceDefaultProxy $domain $service $location $argv
    end

    function getServiceDefaultProxy -a domain service location
        argparse -i "comment=" "path=" "scheme=" "url=" -- $argv
        set -l scheme
        set -l url
        set -l config (getServiceOverrides $argv)
        set -l portKey (getServicePortKey "$service")
        set -l port (yq "$portKey" "$config" | extractPort)

        if [ -n "$_flag_scheme" ]
            set scheme "$_flag_scheme"
        else
            set scheme http
        end

        if [ -n "$_flag_url" ]
            set url "$_flag_url"
        else
            set url "$scheme://127.0.0.1:$port"

            if [ -n "$_flag_path" ]
                set url "$url$_flag_path"
            end
        end

        printf "%s\n" \
            (if [ -n "$_flag_comment" ]
                echo "# $_flag_comment"
            end) \
            "location $location {" \
                "proxy_pass $url;" \
                'proxy_set_header Host $host;' \
                'proxy_set_header X-Real-IP $remote_addr;' \
                'proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;' \
                'proxy_set_header X-Forwarded-Proto $scheme;' \
                'proxy_set_header X-Forwarded-Protocol $scheme;' \
                'proxy_set_header X-Forwarded-Host $http_host;' \
                (getExtraLocationSettings $argv) \
            "}"
    end

    function getExtraLocationSettings -a domain service location
    end

    function initializeServiceInstallation -V dir -V nginxRoot
        set -l root (getServiceRoot $argv)
        sudo mkdir -p (getServiceRoot $argv)
        sudo mkdir -p "$nginxRoot"
        sudo mkdir -p (dirname (getServiceOverrides $argv))
        sudo touch "$root/docker-compose.overrides.yml"
        sudo cp "$dir/docker-compose.yml" "$root"
    end

    function installDockerService -V dir -V nginxRoot
        set -l config (getServiceOverrides $argv)
        set -l servers (getServiceServers $argv | string split0 || true)

        for i in (seq 1 2 (count $servers))
            set -l locations (getServiceLocations $i $argv | string split0 || true)

            for j in (seq 1 3 (count $locations))
                set -l file (mktemp)
                set -l port (getRandomPort)
                set -l service $locations[$j]
                set -l portKey (getServicePortKey "$service")
                set -l exposedPort
                sudo mkdir -p (getServiceRoot $argv)
                sudo mkdir -p "$nginxRoot"
                cp "$config" "$file"

                set exposedPort (yq "$portKey" "$file" | mutatePort $port)
                PORT=$exposedPort yq "$portKey = env(PORT)" "$file" | sudo tee "$config" >/dev/null
            end
        end
    end

    function configureDockerService
        set -l servers (getServiceServers $argv | string split0 || true)
        set -l nginxConfig (__getServiceNginxConfig $argv)

        for i in (seq 1 2 (count $servers))
            set -l domain $servers[(math $i + 1)]
            set -l subdomain $servers[(math $i)]
            set -l locations (getServiceLocations $i $argv | string split0 || true)
            set domain (getServiceDomain "$subdomain" "$domain")

            begin
                printf "%s\n" \
                    "server {" \
                        "listen 80;" \
                        "server_name $domain;" \
                        (getExtraServerConfig $domain $argv)

                for j in (seq 1 3 (count $locations))
                    set -l service $locations[$j]
                    set -l location $locations[(math $j + 1)]
                    set -l comment $locations[(math $j + 2)]

                    if [ -n "$comment" ]
                        set -a argv --comment "$comment"
                    end

                    getServiceLocationConfig $domain $service $location $argv
                end

                echo "}"
            end
        end | nix-shell -p crossplane --run "crossplane format /dev/stdin" | sudo tee "$nginxConfig" >/dev/null

        sudo systemctl restart nginx
    end

    function getExtraBackupPatterns
        echo ""
    end

    function getBackupArgs
        set -l extraPatterns (getExtraBackupPatterns)

        if [ -n "$extraPatterns" ]
            set extraPatterns "|$extraPatterns"
        end

        printf "%s\n" --base-directory (getServiceRoot $argv) --hidden --no-ignore "^(docker-compose\.overrides\.yml|data)\$$extraPatterns"
    end
end