import prompts from 'prompts';
import {alignTimestampToChunk, API, Auth, Logger, ptsToTimestamp, timestampToPts, Utils} from "@solid/libs";
import {CHUNK_SIZE, Obj} from "@solid/types";
import {VNPlayer, VNPlayerRecordingStatus} from '../VNPlayer';

function getCookie(name: string, cookies: string[]): string | undefined {
  for (const cookiePath of cookies) {
    const [cookie/*, path*/] = cookiePath.split("; ");
    const [key, value] = cookie.split("=");
    if (key === name) {
      return value;
    }
  }
  return undefined;
}

const test = async () => {
  const {
    server,
    username,
    password
  } = await prompts([
    {
      type: "text",
      name: 'server',
      message: 'server url (ex: dev1.videonext.net)',
      initial: 'dev1.videonext.net'
    }, {
      type: "text",
      name: 'username',
      message: 'username',
      initial: 'user'
    }, {
      type: "text",
      name: 'password',
      message: 'password',
      initial: 'topse'
    }
  ]);

  try {
    process.env.API_BACKEND = `https://${server}`;

    const api = new API();
    Auth.setAPI(api);
    await Auth.login({
      username: username,
      password: password
    });
    const setCookie = Auth.api?.lastResponseHeaders ? Auth.api?.lastResponseHeaders["set-cookie"] : [];
    const PHPSESSID = getCookie("PHPSESSID", setCookie);
    api.addHeaders({cookie: `PHPSESSID=${PHPSESSID}`});

    const {list} = await api.getObjectList({
      type: "camera",
      withAttributes: true
    });
    const workList: Obj[] = list.filter((camera: Obj) => camera.attributes.STATUS === "ON" && camera.obj === "b77112fc-2528-11ec-9173-00155dd9270b");
    if (workList.length === 0) {
      throw "Camera list is empty";
    }

    // select first camera from server
    const camera = workList[0];
    const obj: string = camera.obj;

    const start = ptsToTimestamp(alignTimestampToChunk(Date.now() - 5 * 60 * 1000));
    const end = start + CHUNK_SIZE;

    //const {url} = await api.getMobileMediaURL({cameraid: obj});
    const urlParameters = {
      cameraid: obj,
      startTime: timestampToPts(start),
      endTime: timestampToPts(end),
      isLocal: true
    };
    let {url} = await api.getMobileMediaURL(urlParameters);

    const base_dir = "./data";

    let storer = new VNPlayer(undefined, {vsync: false, frame_buffers_num: 3, logger: new Logger()});
    let player = new VNPlayer(undefined, {vsync: false, frame_buffers_num: 3, log_level: 'debug'});

    storer.on("recording_status_changed", async (state: VNPlayerRecordingStatus, timestamp: number, filename: string, message: string) => {
      if (!end) {
        return;
      }

      console.log(VNPlayerRecordingStatus[state], new Date(timestamp * 1000), filename, message);

      console.log((state == VNPlayerRecordingStatus.RECORDING_ENDED || state == VNPlayerRecordingStatus.RECORDING_SKIPPED), timestamp * 1000 + CHUNK_SIZE, end, timestamp * 1000 + CHUNK_SIZE >= end);
      if (state == VNPlayerRecordingStatus.RECORDING_STARTED) {
        console.log("Request archive from {{storage}} to offline archive");
      } else
      if (state == VNPlayerRecordingStatus.RECORDING_ERROR) {
        console.error(filename, message);
      } else
      if ((state == VNPlayerRecordingStatus.RECORDING_ENDED
           || state == VNPlayerRecordingStatus.RECORDING_SKIPPED)
          && timestamp * 1000 + CHUNK_SIZE >= end
      ) {
        console.log("play");

        let {url} = await api.getMobileMediaURL(urlParameters);
        player.play(obj, url, 1.0, base_dir);

        await Utils.wait(5000);

        player.teardown();
      }
    });
    await storer.store(obj, url, base_dir);
  }
  catch (e) {
    console.error(e);
  }
};

test();
