import importlib.util
import subprocess
import tempfile
import unittest
from pathlib import Path

spec = importlib.util.spec_from_file_location('delta', Path(__file__).with_name('knowledge_delta.py'))
delta = importlib.util.module_from_spec(spec)
spec.loader.exec_module(delta)


class DeltaTest(unittest.TestCase):
    def test_retry_and_modified_hash(self):
        with tempfile.TemporaryDirectory() as folder:
            root = Path(folder)
            subprocess.run(['git', 'init', '-q', folder], check=True)
            (root / 'a.md').write_text('original')
            (root / 'private.md').write_text('untracked')
            subprocess.run(['git', 'add', 'a.md'], cwd=root, check=True)
            report = delta.scan(root, {}, 12)
            self.assertEqual([x['path'] for x in report['selected']], ['a.md'])
            self.assertEqual(delta.scan(root, {}, 12)['pending'], 1)
            state = delta.acknowledge(root, {}, report, ['a.md'])
            self.assertEqual(delta.scan(root, state, 12)['pending'], 0)
            (root / 'a.md').write_text('changed after scan')
            with self.assertRaises(ValueError):
                delta.acknowledge(root, {}, report, ['a.md'])
            self.assertEqual(delta.scan(root, state, 12)['pending'], 1)
            with self.assertRaises(ValueError):
                delta.acknowledge(root, {}, report, ['private.md'])

    def test_excluded_feedback_and_upstream(self):
        self.assertFalse(delta.eligible('work/team-learning/daily-optimization/x.md'))
        self.assertFalse(delta.eligible('skills/upstream/x.md'))
        self.assertTrue(delta.eligible('skills/example/SKILL.md'))

    def test_partial_batch_does_not_ack_rest(self):
        with tempfile.TemporaryDirectory() as folder:
            root = Path(folder)
            subprocess.run(['git', 'init', '-q', folder], check=True)
            for i in range(6):
                (root / f'{i}.md').write_text(str(i))
            subprocess.run(['git', 'add', '.'], cwd=root, check=True)
            report = delta.scan(root, {}, 4)
            state = delta.acknowledge(root, {}, report, [report['selected'][0]['path']])
            self.assertEqual(delta.scan(root, state, 4)['pending'], 5)


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