import os

import ijson as ijson
from mona_sdk import MonaSingleMessage, Client

# Set the path of the JSON file and the num of objects be batch
DIRECTORY_PATH_TO_RAW_DATA_FILES = "/Users/youvalpolacsek/Mona/youval scripts/data"
PATH_TO_RAW_DATA_FILE = "/home/smadar/workspace/mona-sdk/mona_sdk/site_info.json"
NUMBER_OF_MESSAGES_IN_BATCH = 100000

# Set the client
sdk_client = Client(
    api_key="3b19d07e-50f6-4279-84e8-178f4d6eafe2",
    secret="87a27b54-bb50-4594-bfd6-9377f435ed3f",
    user_id="7ef803b0-ad52-4f3f-856c-dc7bca3a739c",
    raise_authentication_exceptions=True,
    raise_export_exceptions=True,
    override_rest_api_full_url="https://incoming27ca13ae-3e31-4230-88c0-b0146674a3af.monalabs.io/export"
)


def create_a_json_file_from_jsonl(in_file):
    splitted_path = in_file.split("/")
    orig_file_name = splitted_path[-1].split(".")[0]
    out_file_path = f"{'/'.join(splitted_path[:-1])}/{orig_file_name}_proper_json.json"
    with open(out_file_path, "w") as write_fd:
        write_fd.write("[")
        with open(in_file, "r") as read_fd:
            first = True
            for entry in read_fd:
                if first:
                    first = False
                else:
                    write_fd.write(",")
                write_fd.write(entry)

        write_fd.write("]")
    return out_file_path


def is_a_jsonl_file(file_path):
    with open(file_path, "r") as read_fd:
        for entry in read_fd:
            first_char = None
            ind = 0
            max_ind = len(entry)
            while (
                first_char == None or first_char == "\n" or first_char == " "
            ) and ind < max_ind:
                first_char = entry[ind]
                ind += 1
            if first_char != "\n" and first_char != " ":
                if first_char == "[":
                    return False
                else:
                    return True


def send_data_from_file_path(file_path=PATH_TO_RAW_DATA_FILE):
    messages = []
    number_of_messages_left_in_current_batch = NUMBER_OF_MESSAGES_IN_BATCH
    number_of_batches = 0
    total_number_of_messages_sent = 0
    number_of_items_iterated = 0  # Where the script is in the file, how many messages

    if is_a_jsonl_file(file_path):
        file_path = create_a_json_file_from_jsonl(file_path)

    # it already went through (can be different from total_number_of_messages_sent when
    # there are failures).​
    # Set the record keys
    with open(file_path, "r") as read_fd:
        for record in ijson.items(read_fd, "item"):
            messages.append(
                MonaSingleMessage(
                    message=record, contextClass="site_id", contextId=str(record["site_id"])
                )
            )
            number_of_messages_left_in_current_batch -= 1

            # If we processed the number we wanted in a batch, then it's time to send
            # this batch.
            if number_of_messages_left_in_current_batch == 0:
                number_of_items_iterated += NUMBER_OF_MESSAGES_IN_BATCH
                try:
                    sdk_client.export_batch(messages)
                    number_of_batches += 1
                    total_number_of_messages_sent += NUMBER_OF_MESSAGES_IN_BATCH
                    print(
                        f"Successfully sent msgs "
                        f"{number_of_items_iterated - NUMBER_OF_MESSAGES_IN_BATCH} to "
                        f"{number_of_items_iterated}"
                    )
                except Exception:
                    print(
                        f"Failed to send msgs "
                        f"{number_of_items_iterated - NUMBER_OF_MESSAGES_IN_BATCH} to "
                        f"{number_of_items_iterated}"
                    )

                messages = []
                number_of_messages_left_in_current_batch = NUMBER_OF_MESSAGES_IN_BATCH

        # Here we process the leftovers that didn't reach the amount of the full batch.
        number_of_items_iterated += len(messages)
        try:
            ret = sdk_client.export_batch(messages)
            number_of_batches += 1
            total_number_of_messages_sent += len(messages)
            print(
                f"Sent msgs {number_of_items_iterated - len(messages)} to "
                f"{number_of_items_iterated}"
            )
        except Exception:
            print(
                f"Failed to send messages {number_of_items_iterated - len(messages)} to "
                f"{number_of_items_iterated}"
            )
        print(
            f"Sent {total_number_of_messages_sent} messages in {number_of_batches} batches."
        )


def send_data_from_directory(path_to_dir_with_data=DIRECTORY_PATH_TO_RAW_DATA_FILES):
    print(f"Start of iteration over the directory {path_to_dir_with_data}.")
    paths_of_files_with_data_to_send = [
        os.path.join(dirpath, f)
        for (dirpath, dirnames, filenames) in os.walk(path_to_dir_with_data)
        for f in filenames
    ]

    for path_to_file in paths_of_files_with_data_to_send:
        print(path_to_file)
        send_data_from_file_path(path_to_file)

    print(f"Done iterating over the directory {path_to_dir_with_data}")


#send_data_from_directory()

send_data_from_file_path()
