require "http/client"
require "json"
require "base64"
require "openssl"

module ContainerMom
  class K8sClient
    class Error < Exception; end

    def initialize
      @host = ENV["KUBERNETES_SERVICE_HOST"]? || "localhost"
      @port = ENV["KUBERNETES_SERVICE_PORT"]?.try(&.to_i) || 8443
      @token = File.read("/var/run/secrets/kubernetes.io/serviceaccount/token")
      @ca_cert = File.read("/var/run/secrets/kubernetes.io/serviceaccount/ca.crt")
      
      @client = setup_client
    end

    def watch(path : String, &block : JSON::Any -> Nil)
      full_path = "#{path}?watch=true"
      
      response = @client.get(full_path)
      
      case response.status_code
      when 200
        response.body_io.each_line do |line|
          event = JSON.parse(line)
          yield event
        end
      else
        raise Error.new("Failed to watch resources: #{response.status_code} - #{response.body}")
      end
    end

    def patch(path : String, body : String, content_type : String) : Nil
      response = @client.patch(
        path,
        headers: HTTP::Headers{
          "Content-Type" => content_type,
          "Accept" => "application/json",
        },
        body: body
      )

      unless response.success?
        raise Error.new("Failed to patch resource: #{response.status_code} - #{response.body}")
      end
    end

    def create(path : String, body : String) : Nil
      response = @client.post(
        path,
        headers: HTTP::Headers{
          "Content-Type" => "application/json",
          "Accept" => "application/json",
        },
        body: body
      )

      unless response.success?
        raise Error.new("Failed to create resource: #{response.status_code} - #{response.body}")
      end
    end

    def delete(path : String) : Nil
      response = @client.delete(path)

      unless response.success?
        raise Error.new("Failed to delete resource: #{response.status_code} - #{response.body}")
      end
    end

    private def setup_client
      context = OpenSSL::SSL::Context::Client.new
      context.ca_certificates = @ca_cert
      
      client = HTTP::Client.new(@host, @port, context)
      client.before_request do |request|
        request.headers["Authorization"] = "Bearer #{@token}"
      end

      client
    end
  end
end
