require "kubernetes"

# Define types module
module ContainerMom::Types
  # Usage detail structure
  struct UsageDetail
    include Kubernetes::Serializable

    field deployment_name : String
    field region : String
    field cpu : String
    field memory : String
    field hours : Int32
    field cost : Float64

    def initialize(@deployment_name : String, @region : String, @cpu : String, @memory : String, @hours : Int32, @cost : Float64)
    end
  end

  # Usage summary structure
  struct Usage
    include Kubernetes::Serializable

    field current_month_cost : Float64
    field active_deployments : Int32
    field active_regions : Int32
    field total_cpu : Float64
    field total_memory : Float64
    field details : Array(UsageDetail)

    def initialize(@current_month_cost : Float64, @active_deployments : Int32, @active_regions : Int32, @total_cpu : Float64, @total_memory : Float64, @details : Array(UsageDetail))
    end
  end

  # Source credentials structure
  struct SourceCredentials
    include Kubernetes::Serializable

    field username : String
    field password : String
  end

  # Source configuration structure
  struct SourceConfig
    include Kubernetes::Serializable

    field type : String
    field url : String
    field credentials : SourceCredentials?
  end

  # Kubernetes metadata structure
  struct ObjectMeta
    include Kubernetes::Serializable

    field name : String
    field namespace : String?
    field labels : Hash(String, String)?
    field annotations : Hash(String, String)?
  end

  # ContainerDeployment structure
  struct ContainerDeployment
    include Kubernetes::Serializable

    field metadata : ObjectMeta
    field spec : ContainerDeploymentSpec
  end

  # Define the ContainerDeployment spec structure
  struct ContainerDeploymentSpec
    include Kubernetes::Serializable

    field regions : Array(String)
    field resources : Hash(String, String)?
    field domain : Hash(String, String)?
    field billing : Hash(String, String)?
    field source : SourceConfig
  end
end

# Extend Kubernetes::Client with watch functionality
class Kubernetes::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
end

# Define resources module
module ContainerMom::Resources
  extend self

  # Define methods for standard Kubernetes resources
  def get_secret(name : String)
    client = Kubernetes::Client.new
    client.get("/api/v1/secrets/#{name}")
  end

  def get_configmap(name : String)
    client = Kubernetes::Client.new
    client.get("/api/v1/configmaps/#{name}")
  end

  def get_job(name : String)
    client = Kubernetes::Client.new
    client.get("/apis/batch/v1/jobs/#{name}")
  end

  def get_deployment(name : String)
    client = Kubernetes::Client.new
    client.get("/apis/apps/v1/deployments/#{name}")
  end

  def get_service(name : String)
    client = Kubernetes::Client.new
    client.get("/api/v1/services/#{name}")
  end

  def get_ingress(name : String)
    client = Kubernetes::Client.new
    client.get("/apis/networking.k8s.io/v1/ingresses/#{name}")
  end

  def get_containerdeployment(name : String)
    client = Kubernetes::Client.new
    client.get("/apis/app.container.mom/v1alpha1/containerdeployments/#{name}")
  end

  def apply_secret(manifest)
    client = Kubernetes::Client.new
    client.apply("/api/v1/secrets", manifest)
  end

  def apply_configmap(manifest)
    client = Kubernetes::Client.new
    client.apply("/api/v1/configmaps", manifest)
  end

  def apply_job(manifest)
    client = Kubernetes::Client.new
    client.apply("/apis/batch/v1/jobs", manifest)
  end

  def apply_deployment(manifest)
    client = Kubernetes::Client.new
    client.apply("/apis/apps/v1/deployments", manifest)
  end

  def apply_service(manifest)
    client = Kubernetes::Client.new
    client.apply("/api/v1/services", manifest)
  end

  def apply_ingress(manifest)
    client = Kubernetes::Client.new
    client.apply("/apis/networking.k8s.io/v1/ingresses", manifest)
  end

  def apply_containerdeployment(manifest)
    client = Kubernetes::Client.new
    client.apply("/apis/app.container.mom/v1alpha1/containerdeployments", manifest)
  end
end

# Include resources in ContainerMom module
module ContainerMom
  include Types
  include Resources
end
