"""SQS transport exercise. Explicit, ownership-checked cleanup; no business ACK."""
import argparse
import json
import os
from pathlib import Path
import time
import uuid
import boto3
from botocore.exceptions import ClientError


def context():
    region = os.environ['AWS_REGION']
    account = boto3.client('sts', region_name=region).get_caller_identity()['Account']
    if account != os.environ['EXPECTED_ACCOUNT_ID']:
        raise RuntimeError('AWS account mismatch')
    return boto3.client('sqs', region_name=region), region, account


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('action', choices=['create', 'inspect', 'cleanup'])
    parser.add_argument('--manifest', default='sqs-run.json')
    parser.add_argument('--confirm-run')
    args = parser.parse_args()
    sqs, region, account = context()
    path = Path(args.manifest)
    if args.action == 'create':
        # Exclusive file creation prevents overwriting a previous ownership record.
        run = uuid.uuid4().hex
        state = {'run': run, 'region': region, 'account': account, 'queues': {}}
        with path.open('x') as f:
            json.dump(state, f)
        for kind in ('dlq', 'source', 'fifo'):
            name = 'docs-' + run + '-' + kind + ('.fifo' if kind == 'fifo' else '')
            try:
                sqs.get_queue_url(QueueName=name)
            except ClientError as e:
                if e.response['Error']['Code'] not in ('AWS.SimpleQueueService.NonExistentQueue', 'QueueDoesNotExist'):
                    raise
            else:
                raise RuntimeError('Refusing to reuse existing queue')
            attrs = {'SqsManagedSseEnabled': 'true', 'ReceiveMessageWaitTimeSeconds': '20',
                     'VisibilityTimeout': '120', 'MessageRetentionPeriod': '1209600'}
            if kind == 'source':
                attrs['RedrivePolicy'] = json.dumps({'deadLetterTargetArn': state['queues']['dlq']['arn'], 'maxReceiveCount': '5'})
            if kind == 'fifo':
                attrs.update(FifoQueue='true', ContentBasedDeduplication='true')
            url = sqs.create_queue(QueueName=name, Attributes=attrs,
                                   tags={'DocsRun': run, 'Environment': 'sandbox'})['QueueUrl']
            state['queues'][kind] = {'url': url, 'name': name}
            path.write_text(json.dumps(state, indent=2))
            time.sleep(1)  # SQS create-to-use minimum delay.
            arn = sqs.get_queue_attributes(QueueUrl=url, AttributeNames=['QueueArn'])['Attributes']['QueueArn']
            state['queues'][kind]['arn'] = arn
            path.write_text(json.dumps(state, indent=2))
        print('Created run:', run)
        return
    state = json.loads(path.read_text())
    if (state['region'], state['account']) != (region, account):
        raise RuntimeError('Manifest account/region mismatch')
    if args.action == 'cleanup' and args.confirm_run != state['run']:
        raise RuntimeError('--confirm-run must equal the manifest run ID')
    # Validate ALL targets before any deletion. Tags alone are not authorization;
    # the caller also needs a sandbox-only IAM role scoped to docs-* resources.
    missing = set()
    for q in state['queues'].values():
        if not q['name'].startswith('docs-' + state['run'] + '-'):
            raise RuntimeError('Unexpected resource name')
        try:
            arn = sqs.get_queue_attributes(QueueUrl=q['url'], AttributeNames=['QueueArn'])['Attributes']['QueueArn']
        except ClientError as error:
            if args.action == 'cleanup' and error.response['Error']['Code'] in ('AWS.SimpleQueueService.NonExistentQueue', 'QueueDoesNotExist'):
                missing.add(q['url'])
                continue  # A previous cleanup may have partially completed.
            raise
        if arn != f"arn:aws:sqs:{region}:{account}:{q['name']}":
            raise RuntimeError('Queue identity mismatch')
        tags = sqs.list_queue_tags(QueueUrl=q['url']).get('Tags', {})
        if tags.get('DocsRun') != state['run'] or tags.get('Environment') != 'sandbox':
            raise RuntimeError('Queue ownership mismatch')
    for kind, q in state['queues'].items():
        if q['url'] in missing:
            continue
        if args.action == 'cleanup':
            sqs.delete_queue(QueueUrl=q['url'])
        else:
            attrs = sqs.get_queue_attributes(QueueUrl=q['url'], AttributeNames=['All'])['Attributes']
            print(kind, json.dumps(attrs))
    if args.action == 'cleanup':
        path.rename(path.with_name(path.stem + '.' + state['run'] + '.deleted.json'))


if __name__ == '__main__':
    main()
