#!/usr/bin/env python3
"""To run these tests just execute this script."""

import json
import re
import unittest

from robots import (
    consolidate,
    default_value,
    default_values,
    json_to_caddy,
    json_to_haproxy,
    json_to_htaccess,
    json_to_lighttpd,
    json_to_nginx,
    json_to_table,
    json_to_txt,
    list_to_pcre,
)

class RobotsUnittestExtensions:
    def loadJson(self, pathname):
        with open(pathname, "rt") as f:
            return json.load(f)

    def assertEqualsFile(self, f, s):
        with open(f, "rt") as f:
            f_contents = f.read()

        return self.assertMultiLineEqual(f_contents, s)


class TestRobotsTXTGeneration(unittest.TestCase, RobotsUnittestExtensions):
    maxDiff = 8192

    def setUp(self):
        self.robots_dict = self.loadJson("test_files/robots.json")

    def test_robots_txt_generation(self):
        robots_txt = json_to_txt(self.robots_dict)
        self.assertEqualsFile("test_files/robots.txt", robots_txt)


class TestTableMetricsGeneration(unittest.TestCase, RobotsUnittestExtensions):
    maxDiff = 32768

    def setUp(self):
        self.robots_dict = self.loadJson("test_files/robots.json")

    def test_table_generation(self):
        robots_table = json_to_table(self.robots_dict)
        self.assertEqualsFile("test_files/table-of-bot-metrics.md", robots_table)


class TestHtaccessGeneration(unittest.TestCase, RobotsUnittestExtensions):
    maxDiff = 8192

    def setUp(self):
        self.robots_dict = self.loadJson("test_files/robots.json")

    def test_htaccess_generation(self):
        robots_htaccess = json_to_htaccess(self.robots_dict)
        self.assertEqualsFile("test_files/.htaccess", robots_htaccess)


class TestUserAgentPatternGeneration(unittest.TestCase):
    def test_agents_match_only_the_complete_user_agent_by_default(self):
        pattern = re.compile(
            list_to_pcre({"Spider": {}, "ExampleBot": {}}), re.IGNORECASE
        )

        self.assertIsNotNone(pattern.search("Spider"))
        self.assertIsNotNone(pattern.search("spider"))
        self.assertIsNone(pattern.search("Baiduspider"))
        self.assertIsNone(pattern.search("OurCompanyName Test Spider"))
        self.assertIsNone(pattern.search("Mozilla/5.0 ExampleBot/1.0"))

    def test_name_and_version_agents_match_versioned_tokens(self):
        pattern = re.compile(
            list_to_pcre({"Code": {"has_name_and_version": True}}), re.IGNORECASE
        )

        self.assertIsNotNone(pattern.search("Code"))
        self.assertIsNotNone(pattern.search("Mozilla/5.0 Code/1.2.3"))
        self.assertIsNone(pattern.search("https://codeberg.org/example"))

class TestNginxConfigGeneration(unittest.TestCase, RobotsUnittestExtensions):
    maxDiff = 8192

    def setUp(self):
        self.robots_dict = self.loadJson("test_files/robots.json")

    def test_nginx_generation(self):
        robots_nginx = json_to_nginx(self.robots_dict)
        self.assertEqualsFile("test_files/nginx-block-ai-bots.conf", robots_nginx)

class TestHaproxyConfigGeneration(unittest.TestCase, RobotsUnittestExtensions):
    maxDiff = 8192

    def setUp(self):
        self.robots_dict = self.loadJson("test_files/robots.json")

    def test_haproxy_generation(self):
        robots_haproxy = json_to_haproxy(self.robots_dict)
        self.assertEqualsFile("test_files/haproxy-block-ai-bots.txt", robots_haproxy)

class TestRobotsNameCleaning(unittest.TestCase):
    def test_clean_name(self):
        from robots import clean_robot_name

        self.assertEqual(clean_robot_name("Perplexity‑User"), "Perplexity-User")

class TestCaddyfileGeneration(unittest.TestCase, RobotsUnittestExtensions):
    maxDiff = 8192

    def setUp(self):
        self.robots_dict = self.loadJson("test_files/robots.json")

    def test_caddyfile_generation(self):
        robots_caddyfile = json_to_caddy(self.robots_dict)
        self.assertEqualsFile("test_files/Caddyfile", robots_caddyfile)

class TestLighttpdConfigGeneration(unittest.TestCase, RobotsUnittestExtensions):
    maxDiff = 8192

    def setUp(self):
        self.robots_dict = self.loadJson("test_files/robots.json")

    def test_lighttpd_generation(self):
        robots_lighttpd = json_to_lighttpd(self.robots_dict)
        self.assertEqualsFile("test_files/lighttpd-block-ai-bots.conf", robots_lighttpd)


class TestConsolidate(unittest.TestCase, RobotsUnittestExtensions):
    maxDiff = 8192

    def test_new_item(self):
        existing = {}
        self.assertEqual("George Jetson", consolidate(existing, "rosie", "operator", "George Jetson"))
        
    def test_ignores_defaults(self):
        existing = {"rosie": { "operator": "George Jetson"}}
        self.assertEqual("George Jetson", consolidate(existing, "rosie", "operator", default_value))
        
    def test_new_description(self):
        existing = {"rosie": { "description": default_value}}
        self.assertEqual("Rosie is the robot maid from The Jetsons, an American animated sitcom", 
                         consolidate(existing, "rosie", "description", "Rosie is the robot maid from The Jetsons, an American animated sitcom"))

if __name__ == "__main__":
    import os
    os.chdir(os.path.dirname(__file__))

    unittest.main(verbosity=2)
