package ru.kovbasa.playwright;

import com.google.inject.Injector;
import com.microsoft.playwright.Browser;
import com.microsoft.playwright.BrowserContext;
import com.microsoft.playwright.BrowserType;
import com.microsoft.playwright.Page;
import com.microsoft.playwright.Playwright;
import com.microsoft.playwright.Tracing;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Locale;
import org.junit.jupiter.api.extension.AfterEachCallback;
import org.junit.jupiter.api.extension.BeforeEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import ru.kovbasa.config.InjectorProvider;

public class PlaywrightExtension implements BeforeEachCallback, AfterEachCallback {

    private static final String TRACE_DIR = "traces";

    @Override
    public void beforeEach(ExtensionContext context) throws Exception {
        Injector injector = InjectorProvider.getInjector();
        TestConfig config = injector.getInstance(TestConfig.class);
        TestResources resources = injector.getInstance(TestResources.class);

        Playwright playwright = Playwright.create();
        BrowserType browserType = resolveBrowserType(playwright, config.getBrowser());
        Browser browser = browserType.launch(new BrowserType.LaunchOptions()
                .setHeadless(config.isHeadless())
                .setSlowMo(config.getSlowMo()));
        BrowserContext browserContext = browser.newContext();
        Page page = browserContext.newPage();

        page.setDefaultTimeout(config.getTimeoutMs());
        page.setDefaultNavigationTimeout(config.getTimeoutMs());
        page.setViewportSize(1920, 1080);

        browserContext.tracing().start(new Tracing.StartOptions()
                .setScreenshots(true)
                .setSnapshots(true)
                .setSources(true));

        resources.setPlaywright(playwright);
        resources.setBrowser(browser);
        resources.setContext(browserContext);
        resources.setPage(page);

        Files.createDirectories(Path.of(TRACE_DIR));
    }

    @Override
    public void afterEach(ExtensionContext context) throws Exception {
        Injector injector = InjectorProvider.getInjector();
        TestResources resources = injector.getInstance(TestResources.class);
        BrowserContext browserContext = resources.getContext();

        if (browserContext != null) {
            Path tracePath = Path.of(TRACE_DIR, buildTraceFileName(context));
            browserContext.tracing().stop(new Tracing.StopOptions().setPath(tracePath));
        }

        resources.clear();
    }

    private BrowserType resolveBrowserType(Playwright playwright, String browserName) {
        String normalized = browserName.toLowerCase(Locale.ROOT);
        return switch (normalized) {
            case "firefox" -> playwright.firefox();
            case "webkit" -> playwright.webkit();
            default -> playwright.chromium();
        };
    }

    private String buildTraceFileName(ExtensionContext context) {
        String raw = context.getDisplayName();
        String sanitized = raw.replaceAll("[^a-zA-Z0-9._-]", "_");
        return sanitized + ".zip";
    }
}
