import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
import determineFileType from "../util/determineFileType";
import base64UrlEncode from "../util/base64UrlEncode";

describe("Media Utils", () => {
  describe("base64UrlEncode", () => {
    it("should encode string to base64url format", () => {
      expect(base64UrlEncode("hello world")).toBe("aGVsbG8gd29ybGQ");
    });

    it('should replace "+" with "-"', () => {
      // '+' in base64 appears when encoding specific binary data
      expect(base64UrlEncode("hello+world")).toBe("aGVsbG8rd29ybGQ");
    });

    it('should replace "/" with "_"', () => {
      expect(base64UrlEncode("path/to/resource")).toBe("cGF0aC90by9yZXNvdXJjZQ");
    });

    it('should remove trailing "=" characters', () => {
      // Using a string that will produce padding in base64
      expect(base64UrlEncode("padding==")).toBe("cGFkZGluZz09");
    });
  });

  describe("createHmacSha256", () => {
    let createHmacSha256;
    const originalEnv = process.env;

    beforeEach(async () => {
      vi.resetModules();
      process.env = { ...originalEnv };
      process.env.IMGPROXY_KEY = "test-key";

      // Dynamically import the module after setting env var
      const module = await import("../util/createHmacSha256");
      createHmacSha256 = module.default;
    });

    afterEach(() => {
      process.env = originalEnv;
    });

    it("should create a valid HMAC SHA-256 hash", () => {
      const result = createHmacSha256("test-data");
      expect(typeof result).toBe("string");
      expect(result.length).toBeGreaterThan(0);
    });

    it("should produce consistent hashes for the same input", () => {
      const hash1 = createHmacSha256("test-data");
      const hash2 = createHmacSha256("test-data");
      expect(hash1).toBe(hash2);
    });

    it("should produce different hashes for different inputs", () => {
      const hash1 = createHmacSha256("test-data-1");
      const hash2 = createHmacSha256("test-data-2");
      expect(hash1).not.toBe(hash2);
    });
  });

  describe("determineFileType", () => {
    it('should return "auto" when no filetype is provided', () => {
      expect(determineFileType()).toBe("auto");
      expect(determineFileType(null)).toBe("auto");
      expect(determineFileType(undefined)).toBe("auto");
    });

    it('should return "image" for image filetypes', () => {
      expect(determineFileType("image/jpeg")).toBe("image");
      expect(determineFileType("image/png")).toBe("image");
      expect(determineFileType("image/gif")).toBe("image");
    });

    it('should return "video" for video filetypes', () => {
      expect(determineFileType("video/mp4")).toBe("video");
      expect(determineFileType("video/quicktime")).toBe("video");
      expect(determineFileType("video/x-msvideo")).toBe("video");
    });

    it('should return "image" for PDF files', () => {
      expect(determineFileType("application/pdf")).toBe("image");
    });

    it('should return "raw" for other application types', () => {
      expect(determineFileType("application/zip")).toBe("raw");
      expect(determineFileType("application/json")).toBe("raw");
      expect(determineFileType("application/msword")).toBe("raw");
    });

    it('should return "auto" for unrecognized types', () => {
      expect(determineFileType("audio/mpeg")).toBe("auto");
      expect(determineFileType("text/html")).toBe("auto");
      expect(determineFileType("unknown-type")).toBe("auto");
    });
  });
});
