"""
 *
 * This file is part of rasdaman community.
 *
 * Rasdaman community is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Rasdaman community is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU  General Public License for more details.
 *
 * You should have received a copy of the GNU  General Public License
 * along with rasdaman community.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Copyright 2003 - 2016 Peter Baumann / rasdaman GmbH.
 *
 * For more information please see <http://www.rasdaman.org>
 * or contact Peter Baumann via <baumann@rasdaman.com>.
 *
"""
# make sure all string literals are unicode
from __future__ import unicode_literals
import json
from util.string_util import fix_newlines, binary_to_string
from collections import OrderedDict


class History:
    def __init__(self, history_file):
        """
        The history class offers functionality for saving the output of commands and merging them
        into a log file
        :param history_file: the path to the history file
        """
        self.history = OrderedDict()
        self.history_file = history_file
        self.counter = 1

    def add_to_history(self, command, stdout, stderr, return_code, user, start_time, execution_time):
        """
        Adds the command to history
        :param str command: the command that was executed
        :param str stdout: the std output of the command
        :param str stderr: the std error of the command
        :param int return_code: the return code of the command
        :param str user: the user that executed the command
        """
        actual_command = str(self.counter) + " " + str(command)
        self.counter += 1
        self.history[actual_command] = {"out": binary_to_string(stdout),
                                        "err": binary_to_string(stderr),
                                        "code": return_code,
                                        "user": user,
                                        "start_time": start_time,
                                        "execution_time": execution_time}
        self.write_history()

    def log_to_history(self, level, msg):
        """
        Add a log msg at a certain log level to the history
        """
        actual_command = str(self.counter) + " " + level
        msg = binary_to_string(msg)

        self.counter += 1
        self.history[actual_command] = msg
        try:
            self.write_history()
        except Exception as ex:
            self.history[actual_command] = "Output failed to serialize to UTF-8: " + ex
            self.write_history()
            print("Failed serializing message:")
            print(msg)

    def write_history(self):
        """
        Writes the history to the history file
        """
        history_contents = ""
        try:
            history_contents = fix_newlines(str(json.dumps(self.history, indent=4)))
        except Exception as ex:
            print("Failed serializing history as json: " + str(ex))
            history_contents = str(self.history)

        with open(self.history_file, mode="w") as out:
            out.write(history_contents)
