import * as chai from "chai";
import { chaiDom } from "../../../util/chai-dom.mjs";
import { initJSDOM } from "../../../util/jsdom.mjs";

chai.use(chaiDom);
const expect = chai.expect;

let Viewer;

describe("Viewer", function () {
	before(function (done) {
		initJSDOM()
			.then(() => import("../../../../source/components/content/viewer.mjs"))
			.then((module) => {
				Viewer = module.Viewer;
				done();
			})
			.catch((error) => done(error));
	});

	afterEach(() => {
		const mocks = document.getElementById("mocks");
		mocks.innerHTML = "";
	});

	it("renders text/plain without interpreting html", function (done) {
		const mocks = document.getElementById("mocks");
		mocks.innerHTML = `<monster-viewer id="viewer"></monster-viewer>`;

		setTimeout(() => {
			try {
				const viewer = document.getElementById("viewer");
				expect(viewer).instanceof(Viewer);

				viewer.setContent("<strong>raw</strong>\n<script>alert(1)</script>");

				setTimeout(() => {
					try {
						const textNode = viewer.shadowRoot.querySelector('[part="text"]');
						expect(textNode).to.not.equal(null);
						expect(textNode.textContent).to.equal(
							"<strong>raw</strong>\n<script>alert(1)</script>",
						);
						expect(textNode.innerHTML).to.contain("&lt;strong&gt;raw&lt;/strong&gt;");
						done();
					} catch (error) {
						done(error);
					}
				}, 0);
			} catch (error) {
				done(error);
			}
		}, 0);
	});

	it("blocks cross-origin resources in html view", function (done) {
		const mocks = document.getElementById("mocks");
		mocks.innerHTML = `<monster-viewer id="viewer"></monster-viewer>`;

		setTimeout(() => {
			try {
				const viewer = document.getElementById("viewer");
				expect(viewer).instanceof(Viewer);

				viewer.setContent(
					`
						<link rel="stylesheet" href="https://evil.example/tracker.css">
						<script src="https://evil.example/tracker.js"></script>
						<img id="external" src="https://evil.example/pixel.png">
						<img id="local" src="/image.png">
					`,
					"text/html",
				);

				setTimeout(() => {
					try {
						const root = viewer.shadowRoot;
						expect(root.querySelector("link")).to.equal(null);
						expect(root.querySelector("script")).to.equal(null);

						const externalImage = root.querySelector("#external");
						expect(externalImage).to.not.equal(null);
						expect(externalImage.classList.contains("privacyImage")).to.equal(true);
						expect(externalImage.getAttribute("src")).to.match(/^data:image\/gif;base64,/);

						const localImage = root.querySelector("#local");
						expect(localImage).to.not.equal(null);
						expect(localImage.getAttribute("src")).to.equal("/image.png");
						done();
					} catch (error) {
						done(error);
					}
				}, 0);
			} catch (error) {
				done(error);
			}
		}, 0);
	});
});
