/**
 * Pluggable VNC screen-broadcast backends.
 *
 * Per the chosen design (option 1): the streaming method is swappable via
 * STREAM_BACKEND in .env. The default is the real live "Go Live" stream via a
 * selfbot account (only way to get a native Discord video broadcast), with safe
 * fallbacks (noVNC link / periodic screenshots) available without code changes.
 */
import type { AppConfig } from "../config.ts";

/** A live voice session to reuse for single-account Go-Live: the conversation's
 *  own selfbot client + its negotiated voice session_id. The Go-Live stream is
 *  created on THIS session (no second login / voice join), so one account both
 *  hears/speaks (via @discordjs/voice) and broadcasts (via @dank074). */
export interface SharedVoiceSession {
  client: unknown;
  guildId: string;
  channelId: string;
  sessionId: string;
  botId: string;
}

export interface StreamContext {
  guildId: string;
  voiceChannelId: string;
  /** Post an image to the invoking text channel (used by the screenshot backend). */
  postImage?: (png: Buffer, name: string) => Promise<void>;
  /** If present and it returns a session, the selfbot backend broadcasts on the
   *  conversation's existing session instead of a second login (single account). */
  getSharedSession?: () => SharedVoiceSession | null;
}

export interface ScreenStreamer {
  readonly kind: AppConfig["streamBackend"];
  /** Start broadcasting. Returns a short user-facing status/link message. */
  start(ctx: StreamContext): Promise<string>;
  stop(): Promise<void>;
  isActive(): boolean;
}

export async function createStreamer(config: AppConfig): Promise<ScreenStreamer> {
  switch (config.streamBackend) {
    case "selfbot": {
      const { SelfbotStreamer } = await import("./selfbot.ts");
      return new SelfbotStreamer(config);
    }
    case "novnc": {
      const { NoVncStreamer } = await import("./novnc.ts");
      return new NoVncStreamer(config);
    }
    case "screenshot": {
      const { ScreenshotStreamer } = await import("./screenshot.ts");
      return new ScreenshotStreamer(config);
    }
    case "none":
    default:
      return {
        kind: "none",
        async start() {
          return "화면 송출이 비활성화되어 있습니다 (STREAM_BACKEND=none).";
        },
        async stop() {},
        isActive: () => false,
      };
  }
}
