package com.agile611.testng.webdriver;

import java.io.File;
import java.util.List;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import org.openqa.selenium.Proxy;

import net.lightbody.bmp.BrowserMobProxy;
import net.lightbody.bmp.BrowserMobProxyServer;
import net.lightbody.bmp.client.ClientUtil;
import net.lightbody.bmp.core.har.Har;
import net.lightbody.bmp.core.har.HarEntry;

public class StatusCodesTest {
    WebDriver driver;
    BrowserMobProxy proxy;

    @BeforeMethod
    public void setUp() throws Exception {
        // 1. Iniciar el servidor Proxy localmente
        proxy = new BrowserMobProxyServer();
        proxy.start(0); // El puerto 0 le dice que busque cualquier puerto libre

        // 2. Crear el objeto Proxy de Selenium a partir del BrowserMob
        Proxy seleniumProxy = ClientUtil.createSeleniumProxy(proxy);

        // 3. Inyectar el proxy en las opciones de Firefox
        FirefoxOptions options = new FirefoxOptions();
        options.setProxy(seleniumProxy);
        
        // Nota: Si usas Selenium 4.6+, esta línea ya no es necesaria gracias a Selenium Manager
        System.setProperty("webdriver.gecko.driver",
                "src" + File.separator + "test"
                        + File.separator + "resources"
                        + File.separator + "geckodriver-macos");
                        
        driver = new FirefoxDriver(options);
    }

    @AfterMethod
    public void tearDown() {
        // Es crucial apagar ambos servicios para no dejar procesos huérfanos
        if (driver != null) {
            driver.quit();
        }
        if (proxy != null) {
            proxy.stop();
        }
    }

    @Test
    public void ResourceNotFound404() {
        // 4. Iniciar la captura de un nuevo archivo HAR
        proxy.newHar("captura_404");
        driver.navigate().to("http://the-internet.herokuapp.com/status_codes/404");

        // 6. Extraer el HAR generado
        Har har = proxy.getHar();

        // 7. Analizar las entradas de red
        boolean hasError404 = false;
        List<HarEntry> entries = har.getLog().getEntries();
        
        for (HarEntry entry : entries) {
            String url = entry.getRequest().getUrl();
            int statusCode = entry.getResponse().getStatus();
            
            // Filtramos para evaluar solo los recursos que son imágenes
             if (statusCode == 404) {
                    System.err.println("❌ 404 Detectado: " + url);
                    hasError404 = true;
                } else {
                    System.out.println("✅ Recurso cargado correctamente (" + statusCode + "): " + url);
            }
        }
        // 8. El test fallará si al menos una imagen devolvió 404
        Assert.assertTrue(hasError404, "Se encontraron recursos con error 404 en la página.");
    }

    @Test
    public void ResourceFound200() {
       // 4. Iniciar la captura de un nuevo archivo HAR
        proxy.newHar("captura_200");
        driver.navigate().to("http://the-internet.herokuapp.com/status_codes/200");

        // 6. Extraer el HAR generado
        Har har = proxy.getHar();

        // 7. Analizar las entradas de red
        boolean hasError200 = false;
        List<HarEntry> entries = har.getLog().getEntries();
        
        for (HarEntry entry : entries) {
            String url = entry.getRequest().getUrl();
            int statusCode = entry.getResponse().getStatus();
            
            // Filtramos para evaluar solo los recursos que son imágenes
             if (statusCode == 200) {
                    System.err.println("✅ 200 Detectado: " + url);
                    hasError200 = true;
                } else {
                    System.out.println("❌ Recurso NO cargado correctamente (" + statusCode + "): " + url);
            }
        }
        Assert.assertTrue(hasError200, "Se encontraron recursos con  200 en la página.");
    }

    @Test
    public void ResourceRedirect301() {
// 4. Iniciar la captura de un nuevo archivo HAR
        proxy.newHar("captura_301");
        driver.navigate().to("http://the-internet.herokuapp.com/status_codes/301");

        // 6. Extraer el HAR generado
        Har har = proxy.getHar();

        // 7. Analizar las entradas de red
        boolean hasError301 = false;
        List<HarEntry> entries = har.getLog().getEntries();
        
        for (HarEntry entry : entries) {
            String url = entry.getRequest().getUrl();
            int statusCode = entry.getResponse().getStatus();
            
            // Filtramos para evaluar solo los recursos que son imágenes
             if (statusCode == 301) {
                    System.err.println("✅ 301 Detectado: " + url);
                    hasError301 = true;
                } else {
                    System.out.println("❌ Recurso NO cargado correctamente (" + statusCode + "): " + url);
            }
        }
        Assert.assertTrue(hasError301, "Se encontraron recursos con  301 en la página.");
    }

    @Test
    public void ResourceError500() {
        // 4. Iniciar la captura de un nuevo archivo HAR
        proxy.newHar("captura_500");
        driver.navigate().to("http://the-internet.herokuapp.com/status_codes/500");

        // 6. Extraer el HAR generado
        Har har = proxy.getHar();

        // 7. Analizar las entradas de red
        boolean hasError500 = false;
        List<HarEntry> entries = har.getLog().getEntries();
        
        for (HarEntry entry : entries) {
            String url = entry.getRequest().getUrl();
            int statusCode = entry.getResponse().getStatus();
            
            // Filtramos para evaluar solo los recursos que son imágenes
             if (statusCode == 500) {
                    System.err.println("✅ 500 Detectado: " + url);
                    hasError500 = true;
                } else {
                    System.out.println("❌ Recurso NO cargado correctamente (" + statusCode + "): " + url);
            }
        }
        Assert.assertTrue(hasError500, "Se encontraron recursos con  500 en la página.");
    }
}