#! /usr/bin/env perl

# ICON
#
# ---------------------------------------------------------------
# Copyright (C) 2004-2026, DWD, MPI-M, DKRZ, KIT, ETH, MeteoSwiss
# Contact information: icon-model.org
# See AUTHORS.TXT for a list of authors
# See LICENSES/ for license information
# SPDX-License-Identifier: BSD-3-Clause
# ---------------------------------------------------------------

#
# Patches a given namelist in given group at given variable with given value
#
# There are three possibilities:
# a) the namelist group exists and the variable is set:
#    replace the variable value, warn if the value does not change
# b) the namelist group exists, but the variable is not set:
#    add variable assignment at end of namelist group
# c) the namelist group does not exist:
#    add group with single variable assignment at end of file
#

use warnings;
use strict;

# Get command line parameters

@ARGV >= 3 or die "Oops: invalid number of parameters\n".
                  "Usage: patch_namelist <group> <variable> <value>\n";

my $group = shift @ARGV;
my $variable = shift @ARGV;
my $value = shift @ARGV;

# Process input files

my $group_found = 0;
my $variable_found = 0;
my $oldargv;

while(<>) {
    # Handle in-place substitution by renaming and re-opening current file
    if(! defined($oldargv) or $ARGV ne $oldargv) {
        rename($ARGV, "$ARGV.$$.orig") or
            die("Sorry: cannot rename '$ARGV': $!\n");
        open(ARGVOUT, ">$ARGV") or
            die("Sorry: cannot open '$ARGV' for writing: $!\n");
        select(ARGVOUT);
        $oldargv = $ARGV;
    }
    # Parse current line
    if(/^\s*&$group\s*$/..m{^\s*/\s*$}) {
    #if(/^\s*&$group\s*$/) {
        $group_found = 1;
        if(/^(\s*$variable\s*=\s*)(.*?)(\s*)$/) {
            $variable_found = 1;
            my $before = $1;
            my $old_value = $2;
            my $after = $3;
            if($old_value eq $value) {
                warn("Hey: value for '$variable' under '$group' in '$ARGV' is unchanged\n");
            }
            else {
                $_ = $before.$value.$after;
            }
        }
        elsif(m{^\s*/\s*$} && !$variable_found) {
            # Add new variable if not found in namelist group
            print("    $variable = $value\n");
        }
    }
    print;
}
continue {
    if(eof) {
        # Add new namelist group if not found in input file
        unless($group_found) {
            print("&$group\n".
                  "    $variable = $value\n".
                  "/\n");
        }
        $group_found = 0;
        $variable_found = 0;
        unlink("$ARGV.$$.orig") or
            die("Sorry: cannot unlink '$ARGV.$$.orig': $!\n");
    }
}
