#! /usr/bin/env nu
# ------------------------------------ #
# Build and Test docker images locally #
#                run:                  #
#        docker/dev.nu --help       #
# ------------------------------------ #
# NOTE:
# Does not work if built from git worktree branch

let branch = git branch --show-current;
# cp -f Caddyfile .dev-docker/Caddyfile

# --- Constraints --- #
def constraints [
  custom_dockerfile?: path
  features?: string
] {
    # if ($features | str contains "enterprise") {
    #   print "Building in EE mode"
    #   print "Is windmill ee private repo mounted? [Y/n]"; 
    #   let inp = input listen --types [key]

    #   if ($inp.code != "y") {
    #     # print "You can use --auto-substitute(-s) to automatically mount ee private repo (TODO)"
    #     print "Aborted"
    #     return;
    #   }
    # }
  if not ($features | str contains "static_frontend") {
    panic "If you compile without 'static_frontend' you won't be able to load frontend"
  }
  if ($features | str contains "enterprise") and not ($features | str contains "license") {
    panic "If you build enterprise you also need to include 'license' feature"
  } 
}
# --- Patches --- #
# ./Dockerfile
def patch_main_dockerfile [
  features?: string
  wasm_pkg?: string
] {
  let dockerfile = open ./Dockerfile
  # Spread wasm parser
  if $wasm_pkg != null {
    $dockerfile
      | str replace '# -- MACRO-SPREAD-WASM-PARSER-DEV-ONLY -- #' $"COPY ./backend/parsers/windmill-parser-wasm/pkg-($wasm_pkg) ./node_modules/windmill-parser-wasm-($wasm_pkg)"
      | return $in
  }

  print $dockerfile

  return $dockerfile
}

# ./docker/Dockerfile*
def patch_custom_dockerfile [
  custom_dockerfile: path
  features?: string
] {
  open $custom_dockerfile
    | str replace 'ghcr.io/windmill-labs/windmill-ee:dev' (get_ident -f $features)
    | str replace 'ghcr.io/windmill-labs/windmill:dev' (get_ident -f $features)
    | return $in
}

# ./docker-compose.yml
def patch_docker_compose [
  custom_dockerfile?: path
  features?: string
] {
  mut compose = open ./docker-compose.yml 

  $compose.services.windmill_worker.pull_policy = "never"
  $compose.services.windmill_worker_native.pull_policy = "never"
  $compose.services.windmill_server.pull_policy = "never"
  $compose.services.windmill_indexer.pull_policy = "never"

  return ($compose | to yaml)
}

# Build and Test docker images
#
# For more info run:
# docker.nu up --help
# docker.nu build --help
#
# Should be invoked in repo root
def main [] {
  ./docker/dev.nu --help;
}

# TODO:
# Also we need single tmpdir for it
def kill [] {}

# Get tag for dockerfile + features
def "main tag" [
  custom_dockerfile?: path  # Any dockerfile that depends on root Dockerfile
  --features(-f): string # Features that will be passed to base Dockerfile to compile windmill
] {
  get_ident $custom_dockerfile -f $features
}

# Run and Build (if not yet) docker image
def "main up" [
  custom_dockerfile?: path  # Any dockerfile that depends on root Dockerfile
  --features(-f): string = "static_frontend" # Features that will be passed to base Dockerfile to compile windmill
  --wasm-pkg: string # Include unreleased wasm parser in docker image
  --rebuild(-r) # Rebuild if there is existing image with same tag
  --yes(-y) # Say yes for every confirmation (TODO)
  --podman(-p) # Use podman as a backend (TODO)
] {
  constraints $custom_dockerfile $features

  # let base_ident = get_ident -f $features;
  let ident = get_ident $custom_dockerfile -f $features;

  if $rebuild or not (docker images | into string | str contains $ident) {
    let base_ident = get_ident -f $features;

    if $rebuild or not (docker images | into string | str contains $base_ident) {
      print $"Building base image with ident: ($base_ident)"
      docker build . -t ($base_ident) -f (wrap "Dockerfile" (patch_main_dockerfile $features $wasm_pkg)) --build-arg features=($features)
    }

    if $custom_dockerfile != null {
      # let ident = get_ident $custom_dockerfile -f $features;
      print $"Building image by path ($custom_dockerfile) with ident: ($ident)"
      docker build -f (wrap "DockerfileCustom" (patch_custom_dockerfile $custom_dockerfile $features)) -t $ident / 
    }
  } else {
    print $"($ident) was found"
  }

  print $"Running: ($ident)"
  WM_IMAGE=$"($ident)" docker compose -f (wrap "docker-compose.yml" (patch_docker_compose $custom_dockerfile $features)) up 
}

# TODO
def clone_ee_private [] {
  let rev = open backend/ee-repo-ref.txt
  git clone --depth 1 git@github.com:windmill-labs/windmill-ee-private.git .docker.nu/private-ee-repo-rev-($rev)
  # git checkout ddcfdfc18a9833a5fc4e62ad62a265ef1e06a0aa)
}

def get_ident [ custom_dockerfile?: path, --features(-f): string ] {
    let feat_postfix = if $features != null {
      $features |  split row ',' | each { |e| $e | str trim --left --right } | sort | str join "-";
    } else {
      "no-features"
    }

    if $custom_dockerfile != null {
      let df_postfix = $"($custom_dockerfile)" | split row "Dockerfile" | get 1 | str downcase;
      return ($branch | append $df_postfix | append $feat_postfix | str join "__");
    } else {
      return ($branch | append $feat_postfix | str join "-");
    }
}

def wrap [ filename content ] {
  let tmpfile = ".dev-docker-wrapper-" ++ $filename;
  $content | save -f $tmpfile 
  return $tmpfile
}

