require "kubernetes"

module ContainerMom
  # Only initialize K8S_CLIENT in standalone mode
  {% if flag?(:standalone) %}
    K8S_CLIENT = K8sClientWrapper.new
  {% end %}

  class K8sClientWrapper
    @client : Kubernetes::Client

    def initialize
      @client = Kubernetes::Client.new
    end

    def get(path : String, headers = HTTP::Headers.new, *, as type : T.class) forall T
      @client.get(path, headers, as: type)
    end

    def get(path : String, headers = HTTP::Headers.new, &block)
      @client.get(path, headers) { |response| yield response }
    end

    delegate post, put, patch, delete, to: @client

    def watch(path : String, &block : JSON::Any -> Nil)
      watch_path = "#{path}?watch=true"
      get(watch_path) do |response|
        response.body_io.each_line do |line|
          event = JSON.parse(line)
          yield event
        end
      end
    end

    def apply(path : String, manifest : NamedTuple | Hash)
      headers = HTTP::Headers{
        "Content-Type" => "application/apply-patch+yaml",
        "Accept" => "application/json"
      }
      
      # Add apiVersion and kind if not present
      manifest = manifest.is_a?(Hash) ? manifest : manifest.to_h
      manifest = manifest.merge({
        "apiVersion" => path.split("/")[2..3].join("/"),
        "kind" => path.split("/").last.capitalize
      }) unless manifest["apiVersion"]? && manifest["kind"]?

      patch(path, body: manifest.to_json, headers: headers)
    end

    def apply_certificate(manifest)
      apply("/apis/cert-manager.io/v1/certificates", manifest)
    end
  end

  module KubernetesClient
    def self.client
      K8S_CLIENT
    end
  end
end
