#! /usr/bin/python

################################################################################
# This file is part of CMacIonize
# Copyright (C) 2017 Bert Vandenbroucke (bert.vandenbroucke@gmail.com)
#
# CMacIonize is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# CMacIonize is distributed in the hope that it will be useful,
# but WITOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with CMacIonize. If not, see <http://www.gnu.org/licenses/>.
################################################################################

##
# @file get_parameterfile.py
#
# @brief Script that extracts the parameters from a given CMacIonize snapshot
# file and writes them to a parameter file with a given name.
#
# This script takes 2 arguments: the name of an existing CMacIonize snapshot
# file, and the name that should be used for the output.
# The script then extracts the parameters from the snapshot file, and writes
# them to the output file using the correct syntax.
#
# @author Bert Vandenbroucke (bv7@st-andrews.ac.uk)
##

# import modules: h5py is used to read the snapshot file, sys is used to parse
# the command line options, and time is used to generate a time stamp to add to
# the file
import h5py
import sys
import time

##
# @brief Main script routine.
#
# @param args Command line options passed on to the script.
##
def main(args):
    global h5py, time

    # parse command line options
    if len(args) < 3:
        print(
            "Usage: python get_parameterfile.py SNAPSHOT_FILENAME OUTPUT_FILENAME"
        )
        exit()
    snapshot_filename = args[1]
    output_filename = args[2]

    # open the snapshot file for reading
    file = h5py.File(snapshot_filename, "r")

    # check if the Parameters group exists
    if not "Parameters" in file:
        print("Error: Parameters group not found!")
        exit()

    # store the parameters in a dictionary
    attrs = {}
    for item in list(file["/Parameters"].attrs.items()):
        attrs[item[0]] = item[1]

    # generate output. This code is the same as in
    # ParameterFile.cpp::print_contents()
    # see that code for detailed comments
    groupname = []
    stream = ""
    for key in sorted(attrs.keys()):
        keygroups = key.split(":")
        keyname = keygroups[-1]
        keygroups.pop()
        indent = ""
        if len(keygroups) > len(groupname):
            i = 0
            while i < len(groupname) and groupname[i] == keygroups[i]:
                i += 1
            for j in range(i):
                indent += "  "
            for j in range(i, len(groupname)):
                groupname.pop()
            for j in range(i, len(keygroups)):
                groupname.append(keygroups[j])
                stream += indent + keygroups[j] + ":\n"
                indent += "  "
        else:
            while len(keygroups) < len(groupname):
                groupname.pop()
            i = 0
            while i < len(keygroups) and groupname[i] == keygroups[i]:
                i += 1
            for j in range(i):
                indent += "  "
            for j in range(i, len(keygroups)):
                groupname.pop()
            for j in range(i, len(keygroups)):
                groupname.append(keygroups[j])
                stream += indent + keygroups[j] + ":\n"
                indent += "  "

        stream += indent + keyname + ": " + attrs[key].decode("utf-8") + "\n"

    # open the output file
    ofile = open(output_filename, "w")
    # add a time stamp
    timestr = time.strftime("%d/%m/%Y, %H:%M:%S.")
    ofile.write("# File generated by get_parameterfile.py on " + timestr + "\n")
    ofile.write(
        "# Based on the parameters found in " + snapshot_filename + "\n"
    )
    ofile.write(stream)

    # print a status message before exiting
    print("Successfully parsed parameters from", snapshot_filename)
    print("Output was written to", output_filename)


# make sure the main() routine is called
if __name__ == "__main__":
    main(sys.argv)
