import pytest
import tempfile
import os
from pathlib import Path
from src.diff_viewer import (
 parse_diff, DiffFile, DiffHunk, parse_hunk_header, 
 get_line_color, apply_patch_to_file
)

def test_parse_diff_empty() -> None:
 result = parse_diff("")
 assert result == []

def test_parse_diff_none() -> None:
 result = parse_diff(None)  # type: ignore
 assert result == []

def test_parse_simple_diff() -> None:
 diff_text = """--- a/src/test.py
+++ b/src/test.py
@@ -1 +1 @@
-old
+new"""
 result = parse_diff(diff_text)
 assert len(result) == 1
 assert result[0].old_path == "src/test.py"
 assert result[0].new_path == "src/test.py"
 assert len(result[0].hunks) == 1
 assert result[0].hunks[0].header == "@@ -1 +1 @@"

def test_parse_diff_with_context() -> None:
 diff_text = """--- a/src/example.py
+++ b/src/example.py
@@ -10,5 +10,6 @@
def existing_function():
  pass
-    old_line
+    old_line
+    new_line
  more_code"""
 result = parse_diff(diff_text)
 assert len(result) == 1
 assert result[0].old_path == "src/example.py"
 assert len(result[0].hunks) == 1
 hunk = result[0].hunks[0]
 assert hunk.old_start == 10
 assert hunk.old_count == 5
 assert hunk.new_start == 10
 assert hunk.new_count == 6
 assert "-    old_line" in hunk.lines
 assert "+    new_line" in hunk.lines

def test_parse_multiple_files() -> None:
 diff_text = """--- a/file1.py
+++ b/file1.py
@@ -1 +1 @@
-a
+b
--- a/file2.py
+++ b/file2.py
@@ -1 +1 @@
-c
+d"""
 result = parse_diff(diff_text)
 assert len(result) == 2
 assert result[0].old_path == "file1.py"
 assert result[1].old_path == "file2.py"

def test_parse_hunk_header() -> None:
 result = parse_hunk_header("@@ -10,5 +10,6 @@")
 assert result == (10, 5, 10, 6)
  
 result = parse_hunk_header("@@ -1 +1 @@")
 assert result == (1, 1, 1, 1)

def test_diff_line_classification() -> None:
 diff_text = """--- a/test.py
+++ b/test.py
@@ -1,3 +1,4 @@
context line
-removed line
+removed line
+added line
another context"""
 result = parse_diff(diff_text)
 hunk = result[0].hunks[0]
 assert any(line.startswith("-") for line in hunk.lines)
 assert any(line.startswith("+") for line in hunk.lines)
 assert any(line.startswith(" ") or not line.startswith(("-", "+")) for line in hunk.lines)

def test_get_line_color() -> None:
 assert get_line_color("+added") == "green"
 assert get_line_color("-removed") == "red"
 assert get_line_color("@@ -1,3 +1,4 @@") == "cyan"
 assert get_line_color(" context") == None

def test_apply_patch_simple() -> None:
 with tempfile.TemporaryDirectory() as tmpdir:
  test_file = Path(tmpdir) / "test.py"
  test_file.write_text("old\n")
    
  patch = f"""--- a/{test_file.name}
+++ b/{test_file.name}
@@ -1 +1 @@
-old
+new"""
    
  success, msg = apply_patch_to_file(patch, tmpdir)
  assert success
  assert test_file.read_text() == "new\n"

def test_apply_patch_with_context() -> None:
 with tempfile.TemporaryDirectory() as tmpdir:
  test_file = Path(tmpdir) / "example.py"
  test_file.write_text("line 1\nline 2\nline 3\n")
    
  patch = f"""--- a/{test_file.name}
+++ b/{test_file.name}
@@ -1,3 +1,3 @@
-line 1
-line 2
+line one
+line two
line 3"""
    
  success, msg = apply_patch_to_file(patch, tmpdir)
  assert success
  content = test_file.read_text()
  assert "line one" in content
  assert "line two" in content
