from actions_logging.app_logging import logger

SEPARATOR = "$"

def replace_val(line, already_set_data):
    for key, val in already_set_data.items():
        if not line.startswith(key):
            continue
        segments = line.split(key)
        if len(segments) < 2:
            raise RuntimeError("bad pattern recognition")

        rest_of_line = f"{key}".join(segments[1:])
        replaced_line = ''.join([val, rest_of_line])
        return replaced_line
    return line



def render_templated_val(text, already_set_data: dict):
    try:
        segments = text.split(SEPARATOR)
        # no $ sign found in string
        if len(segments) < 2:
            return text
        line_start = segments[0]
        rest_of_line = SEPARATOR.join(segments[1:])
        # remove all extra separator ($)
        while rest_of_line.startswith(SEPARATOR):
            line_start += SEPARATOR
            rest_of_line = rest_of_line[1:]
        # string_with_replace = rest_of_line
        processed_line = replace_val(rest_of_line, already_set_data)
        # $ found but three's no such pattern in already_set_data
        if processed_line == rest_of_line and SEPARATOR not in processed_line:
            return text

        # we did the last replacement and come back from DFS
        if len(processed_line.split(SEPARATOR)) == 1:
            return ''.join([line_start, processed_line])

        # "bar$ENV_NAMEfoo" where ENV_NAME==lala  should result into barlalafoo
        postprocessed_substr = render_templated_val(processed_line, already_set_data)
        return ''.join([line_start, postprocessed_substr])

    except Exception as e:
        raise RuntimeError(f"failed to replace env vars in template string while running render_templated_val: {e}")


def replace_dollar_values(json_data: dict) -> dict:
    try:
        logger.debug(f"current json data: {json_data}")
        logger.info("will iterate over json data and replace dollar values with env vars or already set data")
        new_json_data = {}
        for key in json_data:
            value = json_data[key]
            if (isinstance(value, str) and SEPARATOR not in value) or not isinstance(value, str):
                new_value = value
            else:
                new_value = render_templated_val(value, new_json_data)
            new_json_data[key] = new_value
        logger.info("replacing dollar values in json data done")
        logger.debug(f"new json data: {new_json_data}")
        return new_json_data
    except Exception as e:
        raise RuntimeError(f"error in replace_dollar_values: {e}")
