#!/usr/bin/env python3

import argparse
import json
import subprocess
import sys
from os.path import dirname
from pprint import pprint
from typing import Optional

parser = argparse.ArgumentParser(
    description="Load reference data into a new Object Type."
)
parser.add_argument(
    "phorge_uri",
    help='URI to use for the Phorge server, like "https://we.phorge.it/"',
)


def setup_server(uri):
    global phorge_uri
    phorge_uri = uri


def read_file(filename: str) -> str:
    path = dirname(__file__)

    with open(path + "/" + filename, "rt") as input:
        return input.read()


def arc(*command, input: Optional[str] = None):
    return subprocess.check_output(
        [
            "arc",
            f"--conduit-uri={phorge_uri}",
            *command,
        ],
        input=input,
        text=True,
    )


def call_conduit(method, input: dict):
    input_raw = json.dumps(input)
    result = arc("call-conduit", "--", method, input=input_raw)
    return json.loads(result)


def main():
    args = parser.parse_args()

    if "we.phorge.it" in args.phorge_uri:
        print(
            "Don't use public servers to load this example data "
            "- deploy to your own server!"
        )
        sys.exit(3)

    setup_server(args.phorge_uri)

    # Prep Object Type

    custom_data = read_file("xkcd.config.json")

    create_type_xactions = [
        {
            "type": "name",
            "value": "XKCD Comics",
        },
        {
            "type": "description",
            "value": "Demo data set about romance, sarcasm, math, and language.",
        },
        {
            "type": "customfieldsdef",
            # The value here would be a json-encoded string containing json.
            "value": custom_data,
        },
    ]

    result = call_conduit(
        "semistructured.type.edit", {"transactions": create_type_xactions}
    )

    if result["error"]:
        if (
            'method "semistructured.type.edit" does not exist.'
            in result["errorMessage"]
        ):
            print("The extension is not installed!")
            sys.exit(4)

        print("Error creating type!")
        pprint(result)
        sys.exit(5)

    new_type = result["response"]["object"]
    id = new_type["id"]
    class_phid = new_type["phid"]
    print(f"New Object Type created! Id {id}, phid {class_phid}")
    print(f"Visit it here: {phorge_uri}/semistruct/type/{id}/".replace("//", "/"))

    # Now let's load some objects...
    data_items = json.loads(read_file("xkcd.data.json"))

    for item in data_items:
        print("Creating instance " + item["name"] + "...")

        xactions = [{"type": "classPHID", "value": class_phid}]

        for key in ["name", "description", "rawdata"]:
            xactions.append(
                {
                    "type": key,
                    "value": item[key],
                }
            )

        result = call_conduit(
            "semistructured.instance.edit", {"transactions": xactions}
        )

        custom_fields = [
            "custom.xkcd:id",
            "custom.xkcd:alttext",
            "custom.xkcd:explainLink",
            "custom.xkcd:comicType",
        ]

        if result["error"]:
            print("Error creating instance!")
            pprint(result)
            sys.exit(6)

        item_phid = result["response"]["object"]["phid"]
        print(f"Created {item_phid} {item['name']} - now adding custom fields...")

        xactions = list()
        for key in custom_fields:
            xactions.append(
                {
                    "type": key,
                    "value": item[key],
                }
            )

        result = call_conduit(
            "semistructured.instance.edit",
            {"transactions": xactions, "objectIdentifier": item_phid},
        )

        if result["error"]:
            print("Error updating instance!")
            pprint(result)
            sys.exit(7)

        print("Success")


if __name__ == "__main__":
    main()
