#!/usr/bin/env python3
#
# SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Gardener contributors
#
# SPDX-License-Identifier: Apache-2.0

import json
import pathlib
import sys

import ci.util


dependency_type = ci.util.check_env('DEPENDENCY_TYPE')
if not dependency_type == 'component':
    ci.util.fail(
        "don't know how to upgrade dependency type: "
        f'{dependency_type}'
    )

dependency_name = ci.util.check_env('DEPENDENCY_NAME')
dependency_version = ci.util.check_env('DEPENDENCY_VERSION')

images_file = pathlib.Path(
        ci.util.check_env('REPO_DIR'),
        'imagevector',
        'images.yaml',
)


class ImagesParser(object):
    '''
    a naive YAML-parser crafted for the special case of processing
    gardener's images.yaml file; crafted that way to preserve
    comments/empty lines
    '''
    def __init__(
        self,
        images_file,
        names,
        target_version,
    ):
        self.images_file = images_file
        self.lines = images_file.read_text().split('\n')
        self.names = names
        self.target_version = target_version
        self._line_idx = 0

    def _line(self):
        return self.lines[self._line_idx]

    def _next_line(self):
        self._line_idx += 1
        return self._line()

    def _skip_to_next_entry(self, names):
        while not self._line().startswith('-'):
            self._next_line()
        name = self._line().strip().split(':')[-1].strip()

        if name not in names:
            self._next_line()
            return self._skip_to_next_entry(names)

        # found one of the entries:
        return name

    def _skip_to_next_tag(self):
        self._next_line()
        while not self._line().startswith('-'):
            if self._line().strip().startswith('tag:'):
                return
            self._next_line()
        raise RuntimeError('did not find tag attribute')

    def set_versions(self):
        while self.names:
            try:
                name = self._skip_to_next_entry(self.names)
            except IndexError:
                print(str(self.names))
                ci.util.fail('don\'t know how to update ' + str(self.names))
            self.names.remove(name)
            self._skip_to_next_tag()
            tag_line = self._line()
            indent = len(tag_line) - len(tag_line.lstrip())
            patched_line = ' ' * indent + 'tag: "{version}"'.format(
                version=self.target_version,
            )
            self.lines[self._line_idx] = patched_line

    def write_updated_file(self):
        self.images_file.write_text(
            '\n'.join(self.lines)
        )


# optionally load special cases from first argument given as JSON
injectedSpecialCases = {}
if len(sys.argv) == 2:
    injectedSpecialCases = json.loads(sys.argv[1])

# handle special cases
name = dependency_name.split('/')[-1]
if name in injectedSpecialCases:
    names = injectedSpecialCases[name]
elif name == 'autoscaler':
    names = ['cluster-autoscaler']
elif name == 'vpn2':
    names = ['vpn-server', 'vpn-client']
elif name == 'external-dns-management':
    names = ['dns-controller-manager']
elif name == 'logging':
    names = ['fluent-bit-plugin-installer', 'vali-curator', 'telegraf', 'event-logger', 'tune2fs']
elif name == 'etcd-custom-image':
    names = ['etcd']
elif name == 'egress-filter-refresher':
    names = ['egress-filter']
elif name == 'apiserver-proxy':
    names = ['apiserver-proxy-sidecar']
else:
    names = [name]


parser = ImagesParser(
    images_file=images_file,
    names=names,
    target_version=dependency_version,
)

parser.set_versions()
parser.write_updated_file()
