"""
Simplified test for models.py - no external dependencies required.
"""
import sys
import os

# Add parent directory to path
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from onepasswd.models import PasswordEntry


def test_legacy_format():
    """Test loading legacy v1 format."""
    print("Test 1: Legacy format loading...")
    
    legacy_data = {
        'entries': ['github', 'work'],
        'passwd': 'encrypted_pass_123',
        'time': '1234567890.123'
    }
    
    entry = PasswordEntry.from_dict(legacy_data)
    
    assert entry.entries == ['github', 'work'], "Entries mismatch"
    assert entry.passwd == 'encrypted_pass_123', "Password mismatch"
    assert entry.time == '1234567890.123', "Time mismatch"
    assert entry.version == 1, "Version should be 1"
    assert entry.title is None, "Title should be None"
    assert entry.url is None, "URL should be None"
    
    print("  ✓ Legacy format loads correctly")


def test_new_format():
    """Test loading new v2 format."""
    print("Test 2: New v2 format loading...")
    
    new_data = {
        'entries': ['github', 'work'],
        'passwd': 'encrypted_pass_123',
        'time': '1234567890.123',
        'version': 2,
        'title': 'GitHub Work',
        'url': 'https://github.com',
        'username': 'user@example.com',
        'description': 'Work account',
        'category': 'work',
        'tags': ['dev', 'work']
    }
    
    entry = PasswordEntry.from_dict(new_data)
    
    assert entry.entries == ['github', 'work'], "Entries mismatch"
    assert entry.version == 2, "Version should be 2"
    assert entry.title == 'GitHub Work', "Title mismatch"
    assert entry.url == 'https://github.com', "URL mismatch"
    assert entry.username == 'user@example.com', "Username mismatch"
    assert entry.description == 'Work account', "Description mismatch"
    assert entry.category == 'work', "Category mismatch"
    assert entry.tags == ['dev', 'work'], "Tags mismatch"
    
    print("  ✓ New format loads correctly")


def test_serialization():
    """Test serialization only includes non-empty fields."""
    print("Test 3: Serialization (sparse storage)...")
    
    entry = PasswordEntry(
        entries=['test'],
        passwd='encrypted',
        title='Test Entry',
        url='https://example.com',
        username='',  # Empty - should not be saved
        description=None,  # None - should not be saved
        tags=[]  # Empty list - should not be saved
    )
    
    data = entry.to_dict()
    
    assert 'entries' in data, "Entries must be present"
    assert 'passwd' in data, "Password must be present"
    assert 'title' in data, "Title should be saved"
    assert 'url' in data, "URL should be saved"
    assert 'username' not in data, "Empty username should not be saved"
    assert 'description' not in data, "None description should not be saved"
    assert 'tags' not in data, "Empty tags should not be saved"
    assert data['version'] == 2, "Version should be 2"
    
    print("  ✓ Only non-empty fields are saved")


def test_metadata_inference():
    """Test metadata inference from keywords."""
    print("Test 4: Metadata inference...")
    
    # Known service
    entry1 = PasswordEntry(entries=['github', 'work'], passwd='enc')
    title1, url1 = entry1.infer_metadata()
    assert title1 == 'Github', f"Expected 'Github', got '{title1}'"
    assert url1 == 'https://github.com', f"Expected github URL, got '{url1}'"
    print("  ✓ Known service inference works")
    
    # Domain-like keyword
    entry2 = PasswordEntry(entries=['example.com', 'test'], passwd='enc')
    title2, url2 = entry2.infer_metadata()
    assert title2 == 'Example.com', f"Expected 'Example.com', got '{title2}'"
    assert url2 == 'https://example.com', f"Expected example.com URL, got '{url2}'"
    print("  ✓ Domain inference works")
    
    # Existing metadata takes precedence
    entry3 = PasswordEntry(
        entries=['github'], 
        passwd='enc',
        title='My Custom Title',
        url='https://github.com/custom'
    )
    title3, url3 = entry3.infer_metadata()
    assert title3 == 'My Custom Title', "Should use existing title"
    assert url3 == 'https://github.com/custom', "Should use existing URL"
    print("  ✓ Existing metadata takes precedence")


def test_update_fields():
    """Test update_fields method."""
    print("Test 5: Update fields...")
    
    entry = PasswordEntry(
        entries=['test'],
        passwd='encrypted',
        title='Old Title'
    )
    
    old_modified = entry.modified_time
    
    # Update some fields
    entry.update_fields(
        title='New Title',
        url='https://example.com',
        username='user@example.com'
    )
    
    assert entry.title == 'New Title', "Title should be updated"
    assert entry.url == 'https://example.com', "URL should be updated"
    assert entry.username == 'user@example.com', "Username should be updated"
    assert entry.modified_time != old_modified, "Modified time should change"
    
    print("  ✓ Update fields works correctly")


def test_from_legacy():
    """Test from_legacy class method."""
    print("Test 6: from_legacy() method...")
    
    legacy_data = {
        'entries': ['test', 'legacy'],
        'passwd': 'encrypted123',
        'time': '999.888',
        'deleted': True
    }
    
    entry = PasswordEntry.from_legacy(legacy_data)
    
    assert entry.entries == ['test', 'legacy']
    assert entry.passwd == 'encrypted123'
    assert entry.time == '999.888'
    assert entry.version == 1
    assert entry.deleted is True
    
    print("  ✓ from_legacy() works correctly")


def test_round_trip():
    """Test data round-trip (dict → object → dict)."""
    print("Test 7: Round-trip conversion...")
    
    original = {
        'entries': ['github', 'test'],
        'passwd': 'encrypted',
        'time': '123.456',
        'version': 2,
        'title': 'GitHub Test',
        'url': 'https://github.com',
        'username': 'user@test.com',
        'description': 'Test account',
        'category': 'dev',
        'tags': ['test', 'dev']
    }
    
    # Dict → Object
    entry = PasswordEntry.from_dict(original)
    
    # Object → Dict
    result = entry.to_dict()
    
    # Compare (note: some keys might be added/modified)
    assert result['entries'] == original['entries']
    assert result['passwd'] == original['passwd']
    assert result['version'] == 2
    assert result['title'] == original['title']
    assert result['url'] == original['url']
    assert result['username'] == original['username']
    assert result['description'] == original['description']
    assert result['category'] == original['category']
    assert result['tags'] == original['tags']
    
    print("  ✓ Round-trip conversion preserves data")


def run_tests():
    """Run all tests."""
    print("=" * 60)
    print("Testing onepasswd.models")
    print("=" * 60)
    print()
    
    try:
        test_legacy_format()
        test_new_format()
        test_serialization()
        test_metadata_inference()
        test_update_fields()
        test_from_legacy()
        test_round_trip()
        
        print()
        print("=" * 60)
        print("✅ All tests passed!")
        print("=" * 60)
        print()
        print("Summary:")
        print("  • Legacy v1 format: ✓")
        print("  • New v2 format: ✓")
        print("  • Sparse serialization: ✓")
        print("  • Metadata inference: ✓")
        print("  • Update functionality: ✓")
        print("  • Round-trip conversion: ✓")
        return 0
        
    except AssertionError as e:
        print()
        print("=" * 60)
        print(f"❌ Test failed: {e}")
        print("=" * 60)
        import traceback
        traceback.print_exc()
        return 1
    except Exception as e:
        print()
        print("=" * 60)
        print(f"❌ Unexpected error: {e}")
        print("=" * 60)
        import traceback
        traceback.print_exc()
        return 1


if __name__ == '__main__':
    sys.exit(run_tests())
