"""
Integration tests for Python code minification during addon build process.
Tests verify that the build system correctly applies minification when requested.
"""

import pytest
import tempfile
import zipfile
from pathlib import Path
import shutil
import sys
import os
import json

# Add scripts to path to import build module
sys.path.insert(0, str(Path(__file__).parent.parent.parent / "scripts"))

from build_addon import build_addon, minify_python_code


class TestBuildMinificationIntegration:
    """Integration tests for minification in the build process"""
    
    @pytest.fixture
    def temp_build_env(self):
        """Create a temporary build environment with sample Python files"""
        # Create temp directories
        temp_dir = tempfile.mkdtemp()
        project_root = Path(temp_dir)
        src_dir = project_root / "src"
        build_dir = project_root / "build"
        output_dir = project_root / "dist"
        
        src_dir.mkdir(parents=True)
        build_dir.mkdir(parents=True)
        output_dir.mkdir(parents=True)
        
        # Create sample Python file with comments and docstrings
        sample_code = '''"""Module docstring to be removed"""
# This is a comment
def hello_world():
    """Function docstring to be removed"""
    # Inline comment
    return "Hello, World!"

class MyClass:
    """Class docstring to be removed"""
    def method(self):
        # Another comment
        return 42
'''
        
        (src_dir / "__init__.py").write_text(sample_code)
        (src_dir / "blender_manifest.toml").write_text('[manifest]\nname = "Test"\n')
        
        # Create minimal config files
        config = {
            "project": {"id": "test_addon"},
            "build": {
                "source_dir": "src",
                "dist_dir": "dist",
                "temp_dir": "build/temp",
                "exclude_patterns": ["__pycache__", "*.pyc"]
            }
        }
        
        exclusions = {
            "version_configs": {
                "full": {"exclude_files": [], "exclude_patterns": []},
                "free": {"exclude_files": [], "exclude_patterns": []}
            }
        }
        
        (build_dir / "config.json").write_text(json.dumps(config))
        (build_dir / "file_exclusions.json").write_text(json.dumps(exclusions))
        
        # Create dummy sync_version.py
        sync_script = '''#!/usr/bin/env python3
import sys
if "--version" in sys.argv:
    print("Synchronizing version: 1.0.0")
sys.exit(0)
'''
        (build_dir / "sync_version.py").write_text(sync_script)
        
        yield {
            'project_root': project_root,
            'src_dir': src_dir,
            'output_dir': output_dir,
            'sample_code': sample_code
        }
        
        # Cleanup
        shutil.rmtree(temp_dir, ignore_errors=True)
    
    def test_build_with_minify_flag_produces_minified_python_files(self, temp_build_env, monkeypatch):
        """Test that build with minify=True produces minified .py files in output"""
        # This test will fail because minify parameter doesn't exist in build_addon()
        
        project_root = temp_build_env['project_root']
        output_dir = temp_build_env['output_dir']
        
        # Change to project root for build
        monkeypatch.chdir(project_root)
        
        # Build with minification enabled
        # Expected: build_addon() should accept minify=True parameter
        output_zip = build_addon(
            version_type="full",
            version="1.0.0",
            output_dir=output_dir,
            minify=True  # This parameter doesn't exist yet - will cause TypeError
        )
        
        # Extract and verify minified content
        with zipfile.ZipFile(output_zip, 'r') as zf:
            # Find the __init__.py file in the zip
            init_files = [name for name in zf.namelist() if name.endswith('__init__.py')]
            assert len(init_files) > 0, "No __init__.py found in package"
            
            minified_content = zf.read(init_files[0]).decode('utf-8')
        
        # Verify minification occurred
        assert '# This is a comment' not in minified_content, "Comments should be removed"
        assert '"""Module docstring to be removed"""' not in minified_content, "Module docstrings should be removed"
        assert '"""Function docstring to be removed"""' not in minified_content, "Function docstrings should be removed"
        assert 'def hello_world():' in minified_content, "Function definition should be preserved"
        assert 'return "Hello, World!"' in minified_content, "Function body should be preserved"
    
    def test_build_without_minify_flag_preserves_original_code(self, temp_build_env, monkeypatch):
        """Test that build with minify=False preserves original Python code"""
        # This test will fail because minify parameter doesn't exist
        
        project_root = temp_build_env['project_root']
        output_dir = temp_build_env['output_dir']
        original_code = temp_build_env['sample_code']
        
        monkeypatch.chdir(project_root)
        
        # Build with minification disabled
        output_zip = build_addon(
            version_type="full",
            version="1.0.0",
            output_dir=output_dir,
            minify=False  # This parameter doesn't exist yet - will cause TypeError
        )
        
        # Extract and verify original content preserved
        with zipfile.ZipFile(output_zip, 'r') as zf:
            init_files = [name for name in zf.namelist() if name.endswith('__init__.py')]
            assert len(init_files) > 0
            
            preserved_content = zf.read(init_files[0]).decode('utf-8')
        
        # Verify original code is intact
        assert '# This is a comment' in preserved_content, "Comments should be preserved"
        assert '"""Module docstring to be removed"""' in preserved_content, "Docstrings should be preserved"
        assert 'def hello_world():' in preserved_content
        assert 'return "Hello, World!"' in preserved_content