import { describe, test, expect } from "bun:test";
import { buzzerUrl, buzzerNumber, baseUrl, doorName, key } from "./testCommon";
import { DoorStatus } from "../src/types/DoorStatus";
import { InfoResponse } from "../src/functions/api/door/info";
import { ONBOARDING_DOOR_NAME, ONBOARDING_DOOR_PIN } from "../src/schema/DoorConfig";
import { StatusResponse } from "../src/functions/api/door/status";

if (process.env.STAGE !== 'staging') {
  process.exit(0);
}

// currently these tests only run against STAGING env
describe("buzzer client works", () => {
  test("unknown buzzer should reject", async () => {
    const unknownBuzzResp = await fetch(buzzerUrl + `?From=1`).then(res => res.text());
    expect(unknownBuzzResp).toContain("<Reject");
  });

  test("no auth, should dial fallback numbers", async () => {
    const noAuthBuzzResp = await fetch(buzzerUrl + `?From=${buzzerNumber}`).then(res => res.text());
    expect(noAuthBuzzResp).toContain("<Dial");
  });

  test("sample e2e happy path", async () => {
    // make sure it is locked
    const lockResp = await fetch(baseUrl + `/api/door/status?door=${doorName}`);
    expect(lockResp.status).toBe(200);

    // unlock door
    const authResp = await fetch(baseUrl + `/api/door/auth?door=${doorName}&key=${key}`);
    expect(authResp.status).toBe(200);

    // buzzer should return an unlock
    const buzzerActivatedResp = await fetch(buzzerUrl + `?From=${buzzerNumber}`).then(res => res.text());
    expect(buzzerActivatedResp).toContain("<Play");
    expect(buzzerActivatedResp).not.toContain("fail fast callback");

    // door should now be closed
    const infoResp = await fetch(baseUrl + `/api/door/info?door=${doorName}`).then(res => res.json()) as InfoResponse;
    expect(infoResp.status).toBe(DoorStatus.CLOSED);
  });
});

// CAVEAT, this door is currently manually created, for the purposes of automated onboarding flow
describe("onboardingflag door should exist", () => {
  test("onboarding door exists", async () => {
    // door info
    const authResp = await fetch(baseUrl + `/api/door/info?door=${ONBOARDING_DOOR_NAME}`);
    expect(authResp.status).toBe(200);

    const door = (await authResp.json()) as InfoResponse;
    expect(door.timeout).toBe(15 * 60);

    // this may be flaky, it would fail when a user is onboarding and we are deploying
    expect(door.status).toBe(DoorStatus.CLOSED);
  });

  test("onboarding door does not close after info check", async () => {
    let authResp = await fetch(baseUrl + `/api/door/auth?door=${ONBOARDING_DOOR_NAME}&key=${ONBOARDING_DOOR_PIN}`);
    expect(authResp.status).toBe(200);

    let statusResp = await fetch(baseUrl + `/api/door/info?door=${ONBOARDING_DOOR_NAME}`).then(res => res.json()) as InfoResponse;
    expect(statusResp.status).toBe(DoorStatus.OPEN);

    // open again
    statusResp = await fetch(baseUrl + `/api/door/info?door=${ONBOARDING_DOOR_NAME}`).then(res => res.json()) as InfoResponse;
    expect(statusResp.status).toBe(DoorStatus.OPEN);

    // close it
    authResp = await fetch(baseUrl + `/api/door/auth?door=${ONBOARDING_DOOR_NAME}&key=${ONBOARDING_DOOR_PIN}`);
    expect(authResp.status).toBe(200);

    // door should now be closed
    const infoResp = await fetch(baseUrl + `/api/door/info?door=${ONBOARDING_DOOR_NAME}`).then(res => res.json()) as InfoResponse;
    expect(infoResp.status).toBe(DoorStatus.CLOSED);
  })
});
