"""Generate isolated release workloads from an actual orders-api Deployment."""
import copy
import json
import os
import re
import sys

source = json.load(open(sys.argv[1]))
assert source['kind'] == 'Deployment' and source['metadata']['namespace'] == 'orders'
# Require a fresh same-namespace Service snapshot; fail closed on every overlap.
services = json.load(open(sys.argv[2]))['items']
items = []
for track in ('stable', 'candidate'):
    image = os.environ[f'{track.upper()}_IMAGE']
    if not re.fullmatch(r'.+@sha256:[0-9a-f]{64}', image):
        raise ValueError('Use an approved immutable image digest')
    name = 'orders-' + track
    labels = {'app': name, 'release_track': track}
    template = copy.deepcopy(source['spec']['template'])
    template['metadata']['labels'].update(labels)
    template['metadata']['labels']['app.kubernetes.io/name'] = name
    pod_labels = template['metadata']['labels']
    for service in services:
        selector = service.get('spec', {}).get('selector')
        if not selector or service['metadata']['name'] == name:
            continue
        if all(pod_labels.get(k) == v for k, v in selector.items()):
            raise ValueError('Service selector overlaps new workload: ' + service['metadata']['name'])
    template['metadata'].pop('creationTimestamp', None)
    containers = template['spec']['containers']
    api = [c for c in containers if c['name'] == 'api']
    if len(api) != 1:
        raise ValueError('Expected exactly one api container')
    api[0]['image'] = image
    for constraint in template['spec'].get('topologySpreadConstraints', []):
        constraint['labelSelector'] = {'matchLabels': labels}
    items.append({'apiVersion': 'apps/v1', 'kind': 'Deployment',
                  'metadata': {'name': name, 'namespace': 'orders'},
                  'spec': {'replicas': 3, 'selector': {'matchLabels': labels},
                           'strategy': {'type': 'RollingUpdate', 'rollingUpdate': {'maxSurge': 1, 'maxUnavailable': 0}},
                           'template': template}})
    items.append({'apiVersion': 'v1', 'kind': 'Service',
                  'metadata': {'name': name, 'namespace': 'orders'},
                  'spec': {'selector': labels, 'ports': [{'name': 'http', 'port': 80, 'targetPort': 'http'}]}})
    items.append({'apiVersion': 'policy/v1', 'kind': 'PodDisruptionBudget',
                  'metadata': {'name': name, 'namespace': 'orders'},
                  'spec': {'minAvailable': 2, 'selector': {'matchLabels': labels}}})
print(json.dumps({'apiVersion': 'v1', 'kind': 'List', 'items': items}, indent=2))
