module JanusApi
  extend self

  # Janus admin secret
  ADMIN_SECRET = Rails.application.credentials.dig(
    Rails.env.to_sym, :janus_videoroom_password
  )
  URL = "oegs.derwarteraum.com".freeze

  def list_tokens
    api_request(
      "https://#{URL}/janus-admin", {
        janus: "list_tokens"
      }
    )
  end

  def remove_token(token)
    api_request(
      "https://#{URL}/janus-admin", {
        janus: "remove_token",
        token:
      }
    )
  end

  def new_token
    token = [Time.current.to_datetime, SecureRandom.hex].join(",")
    api_request(
      "https://#{URL}/janus-admin", {
        janus: "add_token",
        token:
      }
    )
    token
  end

  def destroy_videoroom(room_id)
    # Generate new token and register it for Janus
    token = new_token

    # Generate session and handle
    handle_url = get_handle_url_for(token)

    # Destroy room
    result = api_request(
      handle_url, {
        janus: "message",
        body: {
          request: "destroy",
          room: room_id,
          secret: ADMIN_SECRET
        },
        token:
      }
    )

    # Return boolean to indicate success
    result.dig("plugindata", "data", "error").nil?
  end

  def create_videoroom(room_id, pin)
    # Generate new token and register it for Janus
    token = new_token

    # Generate session and handle
    handle_url = get_handle_url_for(token)

    # Create room
    result = api_request(
      handle_url, {
        janus: "message",
        body: {
          request: "create",
          room: room_id,
          publishers: 2,
          is_private: true,
          pin:,
          secret: ADMIN_SECRET
        },
        token:
      }
    )

    # Return boolean to indicate success
    result.dig("plugindata", "data", "error").nil?
  end

  private

  def get_handle_url_for(token)
    session = api_request(
      "https://#{URL}/janus", {
        janus: "create",
        token:
      }
    )
    handle = api_request(
      "https://#{URL}/janus/#{session['data']['id']}", {
        janus: "attach",
        plugin: "janus.plugin.videoroom",
        token:
      }
    )
    "https://#{URL}/janus/#{session['data']['id']}/#{handle['data']['id']}"
  end

  # Generates a new Janus request and returns the result in JSON
  def api_request(url, body)
    require "net/http"
    uri = URI(url)
    http = Net::HTTP.new(uri.host, uri.port)
    http.use_ssl = true
    request = Net::HTTP::Post.new(
      uri.path, { "Content-Type" => "application/json" }
    )
    body[:transaction] = SecureRandom.hex
    body[:admin_secret] = ADMIN_SECRET
    request.body = body.to_json
    response = http.request(request)
    JSON.parse(response.body)
  end
end
