import os
import unittest
import time

from semantica.semantic_extract import NERExtractor, RelationExtractor

# Use environment variable for API key
_GROQ_KEY = os.getenv("GROQ_API_KEY") or os.getenv("GROQ_TEST_API_KEY")
@unittest.skipUnless(_GROQ_KEY, "Groq key not set; skipping live integration test")
class TestGroqRelationsIntegration(unittest.TestCase):
    def setUp(self):
        self.api_key = _GROQ_KEY
        self.model = "llama-3.1-8b-instant"
        # Short, unambiguous finance snippet
        self.text_short = (
            "Apple reported revenue of $4.4 billion in Q1 2024 and provided guidance for FY 2025."
        )
        # Longer text to exercise chunking and ensure no hang
        self.text_long = (
            "Apple reported revenue of $4.4 billion in Q1 2024. "
            "The company also reported growth of 12% year-over-year and provided guidance for FY 2025. "
            "Microsoft reported revenue of $6.1 billion in Q2 2024 and expects sequential growth. "
            "NVIDIA reported record revenue in 2024 Q1 and guided for higher revenue in Q2 2024. "
        ) * 20  # expand length

    def _extract_entities(self, text):
        ner = NERExtractor(
            method="llm",
            provider="groq",
            llm_model=self.model,
            api_key=self.api_key,
            temperature=0.0,
        )
        entities = ner.extract_entities(text, entity_types=["ORGANIZATION", "MONEY", "DATE", "EVENT", "PERCENT"])
        self.assertIsInstance(entities, list)
        return entities

    def test_relations_short_text(self):
        entities = self._extract_entities(self.text_short)
        self.assertGreater(len(entities), 0, "NER should extract entities for short text")

        relation_extractor = RelationExtractor(
            method="llm",
            relation_types=[
                "HAS_REVENUE",
                "HAS_GROWTH",
                "PROVIDES_GUIDANCE",
                "IN_QUARTER",
                "FOR_PERIOD",
                "RELATED_TO",
            ],
            provider="groq",
            llm_model=self.model,
            api_key=self.api_key,
            temperature=0.0,
            verbose=True,
        )

        start = time.time()
        relations = relation_extractor.extract_relations(text=self.text_short, entities=entities)
        elapsed = time.time() - start

        self.assertIsInstance(relations, list)
        # Ensure call completes reasonably fast (network dependent; allow generous bound)
        self.assertLess(elapsed, 60, f"Extraction took too long: {elapsed:.2f}s")
        # Do not strictly assert >0 as model output may vary, but log for diagnostics
        if relations:
            sample = relations[0]
            self.assertTrue(hasattr(sample, "subject") and hasattr(sample, "predicate") and hasattr(sample, "object"))

    def test_relations_long_text_chunking(self):
        entities = self._extract_entities(self.text_long)
        self.assertGreater(len(entities), 0, "NER should extract entities for long text")

        relation_extractor = RelationExtractor(
            method="llm",
            relation_types=["RELATED_TO", "HAS_REVENUE", "IN_QUARTER"],
            provider="groq",
            llm_model=self.model,
            api_key=self.api_key,
            temperature=0.0,
            verbose=True,
        )

        start = time.time()
        relations = relation_extractor.extract_relations(text=self.text_long, entities=entities)
        elapsed = time.time() - start

        self.assertIsInstance(relations, list)
        # Ensure completion (chunked path) and no hang
        self.assertLess(elapsed, 120, f"Chunked extraction took too long: {elapsed:.2f}s")
        if relations:
            for r in relations[:3]:
                self.assertTrue(hasattr(r, "subject") and hasattr(r, "predicate") and hasattr(r, "object"))


if __name__ == "__main__":
    unittest.main()
