"""
Module containing binary_c-python's metadata functions
"""

import datetime
import json
import platform
import time

from binarycpython.utils.dicts import (
    multiply_values_dict,
)
from binarycpython.utils.ensemble import (
    binaryc_json_serializer,
    )

class metadata():
    def __init__(self, **kwargs):
        return

    def add_system_metadata(self):
        """
        Add system's metadata to the grid_ensemble_results, and
        add some system information to metadata.
        """
        # add metadata if it doesn't exist
        if not "metadata" in self.grid_ensemble_results:
            self.grid_ensemble_results["metadata"] = {}

        # add date
        self.grid_ensemble_results["metadata"]['date'] = datetime.datetime.now().strftime("%m/%d/%Y %H:%M:%S")

        # add platform and build information
        try:
            self.grid_ensemble_results["metadata"]['platform'] = platform.platform()
            self.grid_ensemble_results["metadata"]['platform_uname'] = list(platform.uname())
            self.grid_ensemble_results["metadata"]['platform_machine'] = platform.machine()
            self.grid_ensemble_results["metadata"]['platform_node'] = platform.node()
            self.grid_ensemble_results["metadata"]['platform_release'] = platform.release()
            self.grid_ensemble_results["metadata"]['platform_version'] = platform.version()
            self.grid_ensemble_results["metadata"]['platform_processor'] = platform.processor()
            self.grid_ensemble_results["metadata"]['platform_python_build'] = ' '.join(platform.python_build())
            self.grid_ensemble_results["metadata"]['platform_python_version'] = platform.python_version()
        except Exception as e:
            print("platform call failed:",e)
            pass

        try:
            self.grid_ensemble_results["metadata"]['hostname'] = platform.uname()[1]
        except Exception as e:
            print("platform call failed:",e)
            pass

        try:
            self.grid_ensemble_results["metadata"]['duration'] = self.time_elapsed()
        except Exception as e:
            print("Failure to calculate time elapsed:",e)
            pass

        try:
            self.grid_ensemble_results["metadata"]['CPU_time'] = self.CPU_time()
        except Exception as e:
            print("Failure to calculate CPU time consumed:",e)
            pass
        return


    def add_ensemble_metadata(self,combined_output_dict):
        """
        Function to add metadata to the grid_ensemble_results and grid_options
        """
        self.grid_ensemble_results["metadata"] = {}
        self.grid_ensemble_results["metadata"]["population_id"] = self.grid_options["_population_id"]
        self.grid_ensemble_results["metadata"]["total_probability_weighted_mass"] = combined_output_dict["_total_probability_weighted_mass_run"]
        self.grid_ensemble_results["metadata"]["factored_in_probability_weighted_mass"] = False
        if self.grid_options["ensemble_factor_in_probability_weighted_mass"]:
            multiply_values_dict(
                self.grid_ensemble_results["ensemble"],
                1.0
                / self.grid_ensemble_results["metadata"][
                    "total_probability_weighted_mass"
                ],
            )
            self.grid_ensemble_results["metadata"]["factored_in_probability_weighted_mass"] = True
        self.grid_ensemble_results["metadata"]["_killed"] = self.grid_options["_killed"]

        # Add settings of the populations
        all_info = self.return_all_info(
            include_population_settings=True,
            include_binary_c_defaults=True,
            include_binary_c_version_info=True,
            include_binary_c_help_all=True,
        )
        self.grid_ensemble_results["metadata"]["settings"] = json.loads(
            json.dumps(all_info, default=binaryc_json_serializer, ensure_ascii=False)
        )

        ##############################
        # Update grid options
        for x in self._metadata_keylist():
            self.grid_options[x] = combined_output_dict[x]
        self.grid_options["_failed_systems_error_codes"] = list(set(combined_output_dict["_failed_systems_error_codes"]))

    def _metadata_keylist(self):
        return ["_failed_count",
                "_failed_prob",
                "_errors_exceeded",
                "_errors_found",
                "_probtot",
                "_count",
                "_total_mass_run",
                "_total_probability_weighted_mass_run",
                "_zero_prob_stars_skipped",
                "_killed"]