import os
import unittest
import tempfile
from pathlib import Path
from src import project_manager
from src import models
from src.app_controller import AppController

class TestProjectSerialization(unittest.TestCase):
 def setUp(self):
  self.test_dir = tempfile.TemporaryDirectory()
  self.project_path = Path(self.test_dir.name) / "test_project.toml"

 def tearDown(self):
  self.test_dir.cleanup()

 def test_fileitem_roundtrip(self):
  """Verify that FileItem objects survive a save/load cycle."""
  proj = project_manager.default_project("test")
  file1 = models.FileItem(path="src/main.py", auto_aggregate=True, force_full=False)
  file2 = models.FileItem(path="docs/readme.md", auto_aggregate=False, force_full=True)
  proj["files"]["paths"] = [file1, file2]
  
  # Save
  project_manager.save_project(proj, self.project_path)
  
  # Load
  loaded_proj = project_manager.load_project(self.project_path)
  
  paths = loaded_proj["files"]["paths"]
  self.assertEqual(len(paths), 2)
  self.assertIsInstance(paths[0], models.FileItem)
  self.assertEqual(paths[0].path, "src/main.py")
  self.assertTrue(paths[0].auto_aggregate)
  self.assertFalse(paths[0].force_full)
  
  self.assertIsInstance(paths[1], models.FileItem)
  self.assertEqual(paths[1].path, "docs/readme.md")
  self.assertFalse(paths[1].auto_aggregate)
  self.assertTrue(paths[1].force_full)

 def test_backward_compatibility_strings(self):
  """Verify that old-style string paths are converted to FileItem objects by AppController."""
  # Create a project file manually with string paths
  content = """
[project]
name = "legacy"

[files]
base_dir = "."
paths = ["file1.py", "file2.md"]

[discussion]
roles = ["User", "AI"]
"""
  with open(self.project_path, "w") as f:
   f.write(content)
   
  # Load via project_manager (should load as strings)
  proj = project_manager.load_project(self.project_path)
  self.assertEqual(proj["files"]["paths"], ["file1.py", "file2.md"])
  
  # Initialize AppController state logic
  controller = AppController()
  controller.project = proj
  
  # Trigger deserialization (copied from init_state)
  raw_paths = controller.project.get("files", {}).get("paths", [])
  controller.files = []
  for p in raw_paths:
   if isinstance(p, models.FileItem):
    controller.files.append(p)
   elif isinstance(p, dict):
    controller.files.append(models.FileItem.from_dict(p))
   else:
    controller.files.append(models.FileItem(path=str(p)))
    
  self.assertEqual(len(controller.files), 2)
  self.assertIsInstance(controller.files[0], models.FileItem)
  self.assertEqual(controller.files[0].path, "file1.py")
  self.assertIsInstance(controller.files[1], models.FileItem)
  self.assertEqual(controller.files[1].path, "file2.md")

 def test_default_roles_include_context(self):
  """Verify that 'Context' is in default project roles."""
  proj = project_manager.default_project("test")
  self.assertIn("Context", proj["discussion"]["roles"])

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