load("@rules_oci//oci:defs.bzl", "oci_image", "oci_load", "oci_push")
load("@rules_pkg//pkg:tar.bzl", "pkg_tar")

#
# Deployment artifacts (tools needed on the host, not in containers)
#

pkg_tar(
    name = "warmup_tar",
    srcs = ["//src/main/go/net/eagle0/warmup:warmup_linux_amd64"],
    package_dir = "bin",
    remap_paths = {
        "/warmup_linux_amd64": "/warmup",
    },
)

#
# Shared utilities layer (busybox for nc, wget, etc.)
#

pkg_tar(
    name = "busybox_layer",
    srcs = ["@busybox_x86_64//file"],
    package_dir = "/usr/local/bin",
    remap_paths = {
        "file/busybox": "busybox",
    },
    symlinks = {
        "/usr/local/bin/nc": "busybox",
    },
)

pkg_tar(
    name = "busybox_layer_arm64",
    srcs = ["@busybox_aarch64//file"],
    package_dir = "/usr/local/bin",
    remap_paths = {
        "file/busybox": "busybox",
    },
    symlinks = {
        "/usr/local/bin/nc": "busybox",
    },
)

#
# Eagle Server Docker Image
#
# Build: bazel build //ci:eagle_server_image
# Load:  bazel run //ci:eagle_server_load
# Push:  bazel run //ci:eagle_server_push
#

# Package the deploy JAR
pkg_tar(
    name = "eagle_server_jar_layer",
    srcs = ["//src/main/scala/net/eagle0/eagle:eagle_server_deploy.jar"],
    package_dir = "/app",
)

# Package the game resources needed at runtime
pkg_tar(
    name = "eagle_resources_layer",
    srcs = [
        "//src/main/resources/net/eagle0/eagle:beasts",
        "//src/main/resources/net/eagle0/eagle:game_parameters",
        "//src/main/resources/net/eagle0/eagle:headshots",
        "//src/main/resources/net/eagle0/eagle:heroes",
        "//src/main/resources/net/eagle0/eagle:province_map",
        "//src/main/resources/net/eagle0/eagle:settings",
    ],
    package_dir = "/app/resources",
)

oci_image(
    name = "eagle_server_image",
    base = "@eclipse_temurin_25_jre_linux_amd64",
    entrypoint = [
        "java",
        "-Xmx2g",
        "-XX:+UseG1GC",
        # JFR profiling support
        "-XX:+UnlockDiagnosticVMOptions",
        "-XX:+DebugNonSafepoints",  # Required for JFR to see through inlined methods
        "-XX:FlightRecorderOptions=stackdepth=256",
        "-jar",
        "/app/eagle_server_deploy.jar",
    ],
    env = {
        "JAVA_OPTS": "-Xmx2g -XX:+UseG1GC",
    },
    exposed_ports = ["40032/tcp"],
    tars = [
        ":busybox_layer",
        ":eagle_server_jar_layer",
        ":eagle_resources_layer",
    ],
    workdir = "/app",
)

# Load into Docker locally: bazel run //ci:eagle_server_load
oci_load(
    name = "eagle_server_load",
    image = ":eagle_server_image",
    repo_tags = ["eagle0/eagle-server:latest"],
)

# Push to DigitalOcean Container Registry
# Note: No remote_tags here - DigitalOcean converts OCI to Docker format,
# changing the digest and breaking oci_push's tag-by-digest logic.
# Tagging is handled in the CI workflow using crane copy/tag.
oci_push(
    name = "eagle_server_push",
    image = ":eagle_server_image",
    repository = "registry.digitalocean.com/eagle0/eagle-server",
)

#
# Shardok Server Docker Image
#
# Build: bazel build //ci:shardok_server_image
# Load:  bazel run //ci:shardok_server_load
# Push:  bazel run //ci:shardok_server_push
#

# Package the Shardok binary
pkg_tar(
    name = "shardok_binary_layer",
    srcs = ["//src/main/cpp/net/eagle0/shardok:shardok-server"],
    package_dir = "/app",
)

# Package the Shardok resources (battalion types, settings)
pkg_tar(
    name = "shardok_resources_layer",
    srcs = [
        "//src/main/resources/net/eagle0/shardok:battalion_types",
        "//src/main/resources/net/eagle0/shardok:settings",
    ],
    package_dir = "/app/resources",
)

# Package the converted maps
pkg_tar(
    name = "shardok_maps_layer",
    srcs = ["//src/main/resources/net/eagle0/shardok/maps"],
    package_dir = "/app/resources/maps",
)

oci_image(
    name = "shardok_server_image",
    base = "@ubuntu_24_04_linux_amd64",
    entrypoint = ["/app/shardok-server"],
    exposed_ports = [
        "40042/tcp",
        "40052/tcp",
    ],
    tars = [
        ":busybox_layer",
        ":shardok_binary_layer",
        ":shardok_resources_layer",
        ":shardok_maps_layer",
    ],
    workdir = "/app",
)

# Load into Docker locally: bazel run //ci:shardok_server_load
oci_load(
    name = "shardok_server_load",
    image = ":shardok_server_image",
    repo_tags = ["eagle0/shardok-server:latest"],
)

# Push to DigitalOcean Container Registry
# Note: No remote_tags here - DigitalOcean converts OCI to Docker format,
# changing the digest and breaking oci_push's tag-by-digest logic.
# Tagging is handled in the CI workflow using crane copy/tag.
oci_push(
    name = "shardok_server_push",
    image = ":shardok_server_image",
    repository = "registry.digitalocean.com/eagle0/shardok-server",
)

#
# Shardok Server ARM64 Docker Image (for Hetzner on-demand compute)
#
# Build: bazel build //ci:shardok_server_image_arm64 --platforms=//:linux_arm64 --extra_toolchains=@llvm_toolchain_linux_arm64//:all
# Load:  bazel run //ci:shardok_server_load_arm64
# Push:  bazel run //ci:shardok_server_push_arm64
#

# Package the Shardok binary (ARM64 version - must be built with --platforms=//:linux_arm64)
pkg_tar(
    name = "shardok_binary_layer_arm64",
    srcs = ["//src/main/cpp/net/eagle0/shardok:shardok-server"],
    package_dir = "/app",
)

oci_image(
    name = "shardok_server_image_arm64",
    base = "@ubuntu_24_04_linux_arm64_v8",
    entrypoint = ["/app/shardok-server"],
    exposed_ports = [
        "40042/tcp",
        "40052/tcp",
    ],
    tars = [
        # Note: busybox_layer_arm64 omitted - busybox.net has SSL issues
        # Health checks can use the shardok-server binary itself or be added later
        ":shardok_binary_layer_arm64",
        ":shardok_resources_layer",
        ":shardok_maps_layer",
    ],
    workdir = "/app",
)

# Load into Docker locally (ARM64): bazel run //ci:shardok_server_load_arm64
oci_load(
    name = "shardok_server_load_arm64",
    image = ":shardok_server_image_arm64",
    repo_tags = ["eagle0/shardok-server:latest-arm64"],
)

# Push to DigitalOcean Container Registry (for Hetzner deployment)
# Uses same repository as x86 but with arm64- tag prefix
oci_push(
    name = "shardok_server_push_arm64",
    image = ":shardok_server_image_arm64",
    repository = "registry.digitalocean.com/eagle0/shardok-server",
)

#
# Admin Server Docker Image (Go)
#
# Build: bazel build //ci:admin_server_image
# Load:  bazel run //ci:admin_server_load
# Push:  bazel run //ci:admin_server_push
#

# Package the Go admin binary (explicit Linux x86_64 target)
pkg_tar(
    name = "admin_binary_layer",
    srcs = ["//src/main/go/net/eagle0/admin_server:admin_server_linux_amd64"],
    package_dir = "/app",
)

# Package the .e0mj map files for the map editor
pkg_tar(
    name = "admin_maps_layer",
    srcs = ["//src/main/resources/net/eagle0/shardok/maps:maps_json"],
    package_dir = "/app/maps",
)

oci_image(
    name = "admin_server_image",
    base = "@alpine_linux_linux_amd64",
    entrypoint = ["/app/admin_server_linux_amd64"],
    exposed_ports = ["8080/tcp"],
    tars = [
        ":busybox_layer",
        ":admin_binary_layer",
        ":admin_maps_layer",
    ],
    workdir = "/app",
)

# Load into Docker locally: bazel run //ci:admin_server_load
oci_load(
    name = "admin_server_load",
    image = ":admin_server_image",
    repo_tags = ["eagle0/admin-server:latest"],
)

# Push to DigitalOcean Container Registry
oci_push(
    name = "admin_server_push",
    image = ":admin_server_image",
    repository = "registry.digitalocean.com/eagle0/admin-server",
)

#
# JFR Sidecar Docker Image (Go + JDK for jcmd)
#
# This sidecar runs with shared PID namespace to access the Eagle JVM.
# Build: bazel build //ci:jfr_sidecar_image
# Load:  bazel run //ci:jfr_sidecar_load
# Push:  bazel run //ci:jfr_sidecar_push
#

# Package the Go JFR server binary
pkg_tar(
    name = "jfr_sidecar_binary_layer",
    srcs = ["//src/main/go/net/eagle0/jfr_server:jfr_server_linux_amd64"],
    package_dir = "/app",
)

oci_image(
    name = "jfr_sidecar_image",
    # Use JDK base image - we need jcmd to dump JFR recordings
    base = "@eclipse_temurin_25_jdk_linux_amd64",
    entrypoint = ["/app/jfr_server_linux_amd64"],
    exposed_ports = ["8081/tcp"],
    tars = [
        ":jfr_sidecar_binary_layer",
    ],
    workdir = "/app",
)

# Load into Docker locally: bazel run //ci:jfr_sidecar_load
oci_load(
    name = "jfr_sidecar_load",
    image = ":jfr_sidecar_image",
    repo_tags = ["eagle0/jfr-sidecar:latest"],
)

# Push to DigitalOcean Container Registry
oci_push(
    name = "jfr_sidecar_push",
    image = ":jfr_sidecar_image",
    repository = "registry.digitalocean.com/eagle0/jfr-sidecar",
)

#
# Auth Server Docker Image (Go)
#
# This is the external OAuth service that handles OAuth flows and JWT creation.
# Build: bazel build //ci:auth_server_image
# Load:  bazel run //ci:auth_server_load
# Push:  bazel run //ci:auth_server_push
#

# Package the Go auth binary (explicit Linux x86_64 target)
pkg_tar(
    name = "auth_binary_layer",
    srcs = [
        "//src/main/go/net/eagle0/authcli:authcli_linux_amd64",
        "//src/main/go/net/eagle0/authservice:authservice_linux_amd64",
    ],
    package_dir = "/app",
)

# Package the attributions.json for the credits page
pkg_tar(
    name = "auth_attributions_layer",
    srcs = ["//src/main/resources/net/eagle0:attributions"],
    package_dir = "/app",
)

oci_image(
    name = "auth_server_image",
    base = "@alpine_linux_linux_amd64",
    entrypoint = ["/app/authservice_linux_amd64"],
    exposed_ports = [
        "40033/tcp",  # gRPC
        "8080/tcp",  # HTTP OAuth callback
    ],
    tars = [
        ":busybox_layer",
        ":auth_binary_layer",
        ":auth_attributions_layer",
    ],
    workdir = "/app",
)

# Load into Docker locally: bazel run //ci:auth_server_load
oci_load(
    name = "auth_server_load",
    image = ":auth_server_image",
    repo_tags = ["eagle0/auth-server:latest"],
)

# Push to DigitalOcean Container Registry
oci_push(
    name = "auth_server_push",
    image = ":auth_server_image",
    repository = "registry.digitalocean.com/eagle0/auth-server",
)
