#!/usr/bin/env python3
"""Harmless option-injection fixture. Python standard library; no file operations.

Run without arguments for the demonstration; --test runs component tests.
The child parses arguments and prints JSON. It never deletes or opens a file.
"""
import argparse
import json
from pathlib import Path
import re
import subprocess
import sys
import unittest


def child(argv):
    parser = argparse.ArgumentParser(allow_abbrev=False)
    parser.add_argument('--delete', action='store_true')
    parser.add_argument('documents', nargs='*')
    args = parser.parse_args(argv)
    print(json.dumps({'delete': args.delete, 'documents': args.documents}))


def invoke(value, separated):
    # The script and interpreter are trusted fixture inputs, not model output.
    command = [sys.executable]
    if sys.flags.optimize:
        command.append('-O')
    command += [str(Path(__file__).resolve()), '--child']
    if separated:
        command.append('--')
    command.append(value)
    result = subprocess.run(command, shell=False, check=True,
                            capture_output=True, text=True, timeout=5)
    return json.loads(result.stdout)


def approved_document(value):
    # Illustrative application policy: one simple document identifier.
    if type(value) is not str or re.fullmatch(r'doc-[a-z0-9]{1,32}\.txt', value) is None:
        raise ValueError('document identifier rejected')
    # Syntax does not establish tenant membership or authorisation.
    return invoke(value, separated=True)


class BoundaryTests(unittest.TestCase):
    def test_naive_option_changes_mode(self):
        self.assertEqual(invoke('--delete', False), {'delete': True, 'documents': []})

    def test_separator_preserves_option_as_data(self):
        self.assertEqual(invoke('--delete', True),
                         {'delete': False, 'documents': ['--delete']})

    def test_ordinary_document(self):
        self.assertEqual(approved_document('doc-alpha.txt'),
                         {'delete': False, 'documents': ['doc-alpha.txt']})

    def test_spaces_remain_one_operand(self):
        self.assertEqual(invoke('quarterly report.txt', True)['documents'],
                         ['quarterly report.txt'])

    def test_shell_punctuation_is_literal(self):
        self.assertEqual(invoke('report; echo unexpected', True)['documents'],
                         ['report; echo unexpected'])

    def test_double_dash_is_literal_after_separator(self):
        self.assertEqual(invoke('--', True)['documents'], ['--'])

    def test_one_argument_containing_spaces_is_not_split(self):
        self.assertEqual(invoke('--delete doc-alpha.txt', True)['documents'],
                         ['--delete doc-alpha.txt'])

    def test_application_rejects_option(self):
        with self.assertRaises(ValueError):
            approved_document('--delete')

    def test_application_rejects_path_and_response_syntax(self):
        for value in ('../doc-a.txt', '/doc-a.txt', '@doc-a.txt', 'doc-a.txt\n', ''):
            with self.subTest(value=value), self.assertRaises(ValueError):
                approved_document(value)

    def test_application_rejects_types(self):
        for value in (None, 1, True, ['doc-a.txt']):
            with self.subTest(value=value), self.assertRaises(ValueError):
                approved_document(value)

    def test_length_boundary(self):
        self.assertEqual(approved_document('doc-' + 'a' * 32 + '.txt')['delete'], False)
        with self.assertRaises(ValueError):
            approved_document('doc-' + 'a' * 33 + '.txt')

    def test_unknown_option_fails_in_naive_path(self):
        with self.assertRaises(subprocess.CalledProcessError):
            invoke('--unknown', False)


if __name__ == '__main__':
    if sys.argv[1:2] == ['--child']:
        child(sys.argv[2:])
    elif sys.argv[1:] == ['--test']:
        unittest.main(argv=[sys.argv[0]], verbosity=2)
    elif not sys.argv[1:]:
        print('naive:', json.dumps(invoke('--delete', False), sort_keys=True))
        print('separated:', json.dumps(invoke('--delete', True), sort_keys=True))
        try:
            approved_document('--delete')
        except ValueError as exc:
            print('validated:', exc)
    else:
        raise SystemExit('usage: agent-option-injection.py [--test]')
