#!/usr/bin/env python
from typing import Union
import os.path
from funcy import collecting
from populate import populate_string, indent_to
import json
import shutil
import requests
import fire
from skema.infer import from_jsonschema
from skema.to_jsonschema import to_jsonschema
from skema.generate import (
    generate_python,
    generate_graphql,
    generate_types,
    generate_jsonschema,
    temporary_write,
    get_result_file,
)

def filename(path):
    name, _ = os.path.splitext(path)
    return name.split('/')[-1]

def append_to_file(path, string):
    with open(path, "a") as f:
        f.write("\n" + string)


def generate(
    path,
    graphql: Union[str, bool] = False,
    typescript=False,
    python=False,
    jsonschema=False,
    ref=None,
    resolve=False,
    hide=[],
    only=None,
):
    if isinstance(path, list):
        name = '_and_'.join([filename(p) for p in path])
        concatenated = '\n\n'.join([open(p).read() for p in path])
        
        with temporary_write(concatenated, path=name) as path:
            return generate(
                path,
                graphql,
                typescript,
                python,
                jsonschema,
                ref,
                resolve,
                hide,
                only,
            )
    temp: temporary_write = None
    if "http" in path:
        r = requests.get(path, stream=True)
        temp = temporary_write("", path=path.split("/")[-1])
        path = temp.path
        with open(path, "wb") as f:
            shutil.copyfileobj(r.raw, f)
    if not isinstance(hide, list):
        raise Exception("hide argument must be list, like --hide [Json, ObjectId]")
    if graphql and isinstance(graphql, bool):
        generate_graphql(path, hide=hide, only=only)
    elif isinstance(graphql, str):
        generate_graphql(path, result_file=graphql, hide=hide, only=only)

    if jsonschema and isinstance(jsonschema, bool):
        generate_jsonschema(path, ref=ref, resolve=resolve, hide=hide, only=only)
    elif isinstance(jsonschema, str):
        generate_jsonschema(
            path, result_file=jsonschema, ref=ref, resolve=resolve, hide=hide, only=only
        ),
    if python:
        generate_python(path, result_file=None if python is True else python, hide=hide, only=only)

    if typescript and isinstance(typescript, bool):
        generate_types(
            path, ".ts", "--lang typescript --just-types", ref=ref, hide=hide, only=only
        )
    elif isinstance(typescript, str):
        generate_types(
            path,
            ".ts",
            "--lang typescript --just-types",
            result_file=typescript,
            ref=ref,
            hide=hide,
            only=only,
        )
    if temp:
        temp.release()


def parse(path, target=None, root="Root"):
    target_path = target or get_result_file(path, ".skema")
    with open(path) as f:
        schema = json.loads(f.read())
        with open(target_path, "w") as f:
            skema = from_jsonschema(schema, ref_name=root)
            f.write(skema)


fire.Fire(dict(generate=generate, parse=parse))

