"""

    AUTHOR:

        Khushal P Soonderji

    DATE:

        Create: Saturday, 18th May, 2022
        Update: Thursday, 22nd Aug. 2024

    OBJECTIVE:

        To provide an easy way to work with '.json' data and files.

    REFERENCES:

        1) https://www.w3schools.com/python/python_json.asp

    DOWNLOADS:

        N/A

"""


#   *****************************************************************************************************************
#  *****                                                                                                          ****
# ***                                                   IMPORT                                                      ***
#  *****                                                                                                          ****
#   *****************************************************************************************************************


# To make sibling directories accessible for imports:
import sys
sys.path.append(".")
sys.path.append("..")

# System-level activities:
import io

# To work with the JSON standard:
import json

# To work with files:
from utils_v2.system import files


#   *****************************************************************************************************************
#  *****                                                                                                          ****
# ***                                           MACROS / ONE-TIME INIT                                              ***
#  *****                                                                                                          ****
#   *****************************************************************************************************************


# --- Nothing Yet


#   *****************************************************************************************************************
#  *****                                                                                                          ****
# ***                                                VARIABLES                                                      ***
#  *****                                                                                                          ****
#   *****************************************************************************************************************


# --- Nothing Yet


#   *****************************************************************************************************************
#  *****                                                                                                          ****
# ***                                                  FUNCTIONS                                                    ***
#  *****                                                                                                          ****
#   *****************************************************************************************************************


def from_string(json_data):

    """
    Decodes a JSON string to a pythonic variable like a dict.
    :param json_data: The JSON string to decode.
    :return: The decoded pythonic variable.
    """

    python_data = json.loads(json_data)
    return python_data


# ---------------------------------------------------------------------------------------------------------------------


def to_string(
        python_data,
        indent = 4,
        default = None,
        separators = None,
        no_space = False
):

    """
    Converts the given pythonic data to a JSON string.
    :param python_data: The input data like a dict.
    :param indent: The tab-width for pretty presentation.
    :param default: The function to use on something that cannot be directly parsed into a JSON string.
    :param separators: Custom separators to use.
    :param no_space: If you want a dense JSON string that saves memory by not using spaces or tabs or line-breaks. Not
        good for human readability, very good for saving memory. WARNING: THIS OVERRIDES EVERY OTHER PARAMETER EXCEPT
        'default'.
    :return: The JSON string representation of the input pythonic data.
    """

    if no_space:
        json_data = json.dumps(
            python_data,
            default = default,
            separators = (',', ':')
        )

    else:
        json_data = json.dumps(
            python_data,
            indent = indent,
            default = default,
            separators = separators
        )

    return json_data


# ---------------------------------------------------------------------------------------------------------------------


def from_file(file):

    """
    Reads a JSON file and returns it as a pythonic variable like a dict.
    :param file: The path to the file on the disk or a file held in RAM as a BytesIO object.
    :return: The decoded pythonic variable.
    """

    if isinstance(file, io.BytesIO):
        file.seek(0)
        json_data = file.getvalue()
    else: json_data = files.read_file(file)
    python_data = from_string(json_data)
    return python_data


# ---------------------------------------------------------------------------------------------------------------------


def to_file(
        file,
        python_data,
        indent = 4,
        default = None,
        separators = None,
        no_space = False
):

    """

    :param file: Either a path to a file on disk, or a buffer in RAM in the form of a BytesIO object.
    :param python_data: The pythonic data to be converted to the JSON string.
    :param indent: The tab-width for pretty presentation.
    :param default: The function to use on something that cannot be directly parsed into a JSON string.
    :param separators: Custom separators to use.
    :param no_space: If you want a dense JSON string that saves memory by not using spaces or tabs or line-breaks. Not
        good for human readability, very good for saving memory. WARNING: THIS OVERRIDES EVERY OTHER PARAMETER EXCEPT
        'default'.
    :return: True/False if a path was given, else the same BytesIO object with the written JSON data.
    """

    json_data = to_string(
        python_data,
        indent = indent,
        default = default,
        separators = separators,
        no_space = no_space
    )

    if isinstance(file, io.BytesIO):
        file.write(json_data.encode("utf-8"))
        file.seek(0)
        return file

    else:
        try:
            files.write_file(file, json_data, mode = "w")
            return True
        except: return False


#   *****************************************************************************************************************
#  *****                                                                                                          ****
# ***                                               MAIN PROGRAM                                                    ***
#  *****                                                                                                          ****
#   *****************************************************************************************************************


if __name__ == "__main__":

    pass
