package golem:video-generation@1.0.0;

interface types {
  variant video-error {
    invalid-input(string),
    unsupported-feature(string),
    quota-exceeded,
    generation-failed(string),
    cancelled,
    internal-error(string),
  }

  variant media-input {
    text(string),
    image(reference),
    video(base-video),
  }

  record reference {
    data: input-image,
    prompt: option<string>,
    role: option<image-role>,
  }

  enum image-role {
    first,
    last,
  }

  record input-image {
    data: media-data,
  }

  record base-video {
    data: media-data,
  }

  record narration {
    data: media-data,
  }

  variant media-data {
    url(string),
    bytes(raw-bytes),
  }

  record raw-bytes {
    bytes: list<u8>,
    mime-type: string,
  }

  record static-mask {
    mask: input-image,
  }

  record dynamic-mask {
    mask: input-image,
    trajectories: list<position>,
  }

  record position {
    x: u32,
    y: u32,
  }

  variant camera-movement {
    simple(camera-config),
    down-back,
    forward-up,
    right-turn-forward,
    left-turn-forward,
  }

  record camera-config {
    horizontal: f32,
    vertical: f32,
    pan: f32,
    tilt: f32,
    zoom: f32,
    roll: f32,
  }

  record generation-config {
    negative-prompt: option<string>,
    seed: option<u64>,
    scheduler: option<string>,
    guidance-scale: option<f32>,
    aspect-ratio: option<aspect-ratio>,
    duration-seconds: option<f32>,
    resolution: option<resolution>,
    model: option<string>,
    enable-audio: option<bool>,
    enhance-prompt: option<bool>,
    provider-options: option<list<kv>>,
    lastframe: option<input-image>,
    static-mask: option<static-mask>,
    dynamic-mask: option<dynamic-mask>,
    camera-control: option<camera-movement>,
  }

  enum aspect-ratio {
    square,
    portrait,
    landscape,
    cinema,
  }

  enum resolution {
    sd,
    hd,
    fhd,
    uhd,
  }

  record kv {
    key: string,
    value: string,
  }

  record video {
    uri: option<string>,
    base64-bytes: option<list<u8>>,
    mime-type: string,
    width: option<u32>,
    height: option<u32>,
    fps: option<f32>,
    duration-seconds: option<f32>,
    generation-id: option<string>,
  }

  variant job-status {
    pending,
    running,
    succeeded,
    failed(string),
  }

  record video-result {
    status: job-status,
    videos: option<list<video>>,
  }

  record text-to-speech {
    text: string,
    voice-id: string,
    language: voice-language,
    speed: f32,
  }

  variant audio-source {
    from-text(text-to-speech),
    from-audio(narration),
  }

  record voice-info {
    voice-id: string,
    name: string,
    language: voice-language,
    preview-url: option<string>,
  }

  enum voice-language {
    en,
    zh
  }

  enum single-image-effects {
    bloombloom,
    dizzydizzy,
    fuzzyfuzzy,
    squish,
    expansion,
    anime-figure,
    rocketrocket,
  }

  enum dual-image-effects {
    hug,
    kiss,
    heart-gesture,
  }

  record dual-effect {
    effect: dual-image-effects,
    second-image: input-image,
  }

  variant effect-type {
    single(single-image-effects),
    dual(dual-effect),
  }

  variant lip-sync-video {
    video(base-video),
    video-id(string),
  }
}

interface video-generation {
  use types.{media-input, generation-config, video-result, video-error};

  generate: func(input: media-input, config: generation-config) -> result<string, video-error>;
  poll: func(job-id: string) -> result<video-result, video-error>;
  cancel: func(job-id: string) -> result<string, video-error>;
}

interface lip-sync {
  use types.{base-video, audio-source, video-error, voice-info, lip-sync-video};

  generate-lip-sync: func(
    video: lip-sync-video,
    audio: audio-source,
  ) -> result<string, video-error>;

  list-voices: func(language: option<string>) -> result<list<voice-info>, video-error>;
}

interface advanced {
  use types.{video-error, kv, base-video, generation-config, input-image, effect-type};

  record extend-video-options {
    video-id: string,
    prompt: option<string>,
    negative-prompt: option<string>,
    cfg-scale: option<f32>,
    provider-options: option<list<kv>>,
  }
  
  extend-video: func(
    options: extend-video-options
  ) -> result<string, video-error>;

  upscale-video: func(
    input: base-video,
  ) -> result<string, video-error>;

  record generate-video-effects-options {
    input: input-image,
    effect: effect-type,
    model: option<string>,
    duration: option<f32>,
    mode: option<string>,
  }
  
  generate-video-effects: func(
    options: generate-video-effects-options
  ) -> result<string, video-error>;

  record mult-image-generation-options {
    input-images: list<input-image>,
    prompt: option<string>,
    config: generation-config,
  }
  
  multi-image-generation: func(
    options: mult-image-generation-options
  ) -> result<string, video-error>;
}

world video-library {
  import types;
  import video-generation;
  import lip-sync;
  import advanced;
  
  export video-generation;
  export lip-sync;
  export advanced;
  export types;
}
