from dagster import check, seven
from dagster.core.types.dagster_type import DagsterType, DagsterTypeKind

PICKLE_PROTOCOL = 2


def is_json_serializable(value):
    try:
        seven.json.dumps(value)
        return True
    except TypeError:
        return False


def read_value(dagster_type, value):
    check.inst_param(dagster_type, "dagster_type", DagsterType)
    check.dict_param(value, "value")
    check.invariant(
        list(value.keys()) in [["value"], ["file"]],
        "Malformed value received with keys: {bad_keys}, expected ['value'] or ['file']".format(
            bad_keys="[{keys}]".format(
                keys=", ".join(["'{key}'".format(key=key) for key in value.keys()])
            )
        ),
    )
    if "value" in value:
        return value["value"]
    else:
        return dagster_type.serialization_strategy.deserialize_from_file(value["file"])


def write_value(dagster_type, value, target_file):
    check.inst_param(dagster_type, "dagster_type", DagsterType)
    if dagster_type.kind == DagsterTypeKind.SCALAR or (
        dagster_type.kind == DagsterTypeKind.ANY and is_json_serializable(value)
    ):
        return {"value": value}
    else:
        dagster_type.serialization_strategy.serialize_to_file(value, target_file)
        return {"file": target_file}
