#!/bin/env fish
begin
    set -l dir (status dirname)
    set -l root /usr/local/lib
    set -l secretsFile "docker-compose.secrets.yml"
    set -l nginxRoot "/etc/nginx/conf.d"
    set -l portPattern "^\([.[:digit:]]\+:\)\([[:digit:]]\+\)\(:[[:digit:]]\+\)"
    source "$dir/../../../../lib/software.fish"

    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 __getServiceNginxConfig -V nginxRoot
        echo "$nginxRoot/$(getServiceName $argv).conf"
    end

    function getServiceSecretsConfig -V secretsFile
        echo "$(getServiceRoot $argv)/$secretsFile"
    end

    function __getServicePortKey -V secretsFile -a name
        echo ".services.$name.ports[0]"
    end

    function initializeServiceInstallation -V nginxRoot
        mkdir -p (getServiceRoot $argv)
        mkdir -p "$nginxRoot"
        mkdir -p (dirname (getServiceSecretsConfig $argv))
    end

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

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

            for j in (seq 1 4 (count $locations))
                set -l file (mktemp)
                set -l port (random 49152 65535)
                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 --raw-output "$portKey" "$file" | sed "s/$portPattern/\1$port\3/")
                PORT=$exposedPort yq -y "$portKey = env.PORT" "$file" | sudo tee "$config" >/dev/null
            end
        end
    end

    function configureDockerService -V portPattern
        set -l config (getServiceSecretsConfig $argv)
        set -l servers (getServiceServers $argv | string split0)
        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)

            if [ -z "$domain" ]
                set domain (getMachineFQDN)
            end

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

            begin
                printf "%s\n" \
                    "server {" \
                        "listen 80;" \
                        "server_name $domain;"

                for j in (seq 1 2 (count $locations))
                    set -l service $locations[$j]
                    set -l location $locations[(math $j + 1)]
                    set -l portKey (__getServicePortKey "$service")
                    set -l port (yq --raw-output "$portKey" "$config" | sed "s/$portPattern/\2/")

                    printf "%s\n" \
                        "location $location {" \
                            "proxy_pass http://127.0.0.1:$port;" \
                            '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;' \
                        "}"
                end

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

        sudo systemctl restart nginx
    end

    function getBackupArgs -V root
        printf "%s\n" --hidden --no-ignore . --exclude "docker-compose.yml" "$root"
    end
end