"""MIT. Forced SQL tool, one bounded repair, checker executes in a sandbox."""
import json
from pathlib import Path
import sys

sys.path.insert(0, str(Path(__file__).resolve().parent.parent / 'lib'))
from sandbox import score as sandbox_score


def request(item, config):
    return {
        'messages': [
            {'role': 'system', 'content': config['prompt']},
            {'role': 'user', 'content': config['schema_sql'] + '\nQuestion: ' + item['text']},
        ],
        'tools': [{'type': 'function', 'function': {
            'name': 'submit_sql', 'description': 'Submit one read-only SQLite query.',
            'parameters': {'type': 'object', 'properties': {
                'sql': {'type': 'string'}, 'explanation': {'type': 'string'},
            }, 'required': ['sql', 'explanation'], 'additionalProperties': False},
        }}],
        'tool_choice': config['tool_choice'], 'parallel_tool_calls': False,
        'max_tokens': config['max_tokens'], 'reasoning_effort': config['reasoning_effort'],
    }


def generate(item, config, call):
    payload = request(item, config)
    response = call(payload)
    calls = response['choices'][0]['message'].get('tool_calls') or []
    try:
        if len(calls) != 1 or calls[0]['function']['name'] != 'submit_sql':
            raise ValueError('expected exactly one SQL call')
        arguments = json.loads(calls[0]['function']['arguments'])
        if not isinstance(arguments, dict):
            raise ValueError('expected object')
    except (ValueError, KeyError, TypeError):
        arguments = {}
    # The checker executes only in a fresh OS sandbox. Gold accuracy is never
    # fed back: only syntax/safety validity controls the single repair request.
    checked = sandbox_score(Path(__file__).with_name('check.py'), item, arguments, config)
    if checked['secondary']['invalid_sql_before_retry']['score']:
        payload['messages'].append({'role': 'user', 'content': 'The previous response was not a single valid read-only SQLite query. Submit one corrected query. Previous SQL: ' + str(arguments.get('sql', ''))[:20000]})
        call(payload)


def plan_requests(item, config):
    first = request(item, config)
    second = request(item, config)
    second['messages'].append({'role': 'user', 'content': 'Repair invalid SQLite. Previous SQL: ' + 'query ' * config['max_tokens']})
    return [first, second]
