def to_map(raw_metadata):
    return {tuple(md["breadcrumb"]): md["metadata"] for md in raw_metadata}


def to_list(compiled_metadata):
    return [{"breadcrumb": k, "metadata": v} for k, v in compiled_metadata.items()]


def delete(compiled_metadata, breadcrumb, k):
    del compiled_metadata[breadcrumb][k]


def write(compiled_metadata, breadcrumb, k, val):
    if val is None:
        raise Exception()
    if breadcrumb in compiled_metadata:
        compiled_metadata.get(breadcrumb).update({k: val})
    else:
        compiled_metadata[breadcrumb] = {k: val}
    return compiled_metadata


def get(compiled_metadata, breadcrumb, k):
    return compiled_metadata.get(breadcrumb, {}).get(k)


def get_standard_metadata(
    schema=None,
    schema_name=None,
    key_properties=None,
    valid_replication_keys=None,
    replication_method=None,
    **kwargs,
):
    mdata = {}

    if key_properties is not None:
        mdata = write(mdata, (), "table-key-properties", key_properties)
    if replication_method:
        mdata = write(mdata, (), "forced-replication-method", replication_method)
    if valid_replication_keys is not None:
        mdata = write(mdata, (), "valid-replication-keys", valid_replication_keys)

    for k, v in kwargs.items():
        mdata = write(mdata, (), k, v)

    if schema:
        mdata = write(mdata, (), "inclusion", "available")

        if schema_name:
            mdata = write(mdata, (), "schema-name", schema_name)
        for field_name in schema["properties"].keys():
            if key_properties and field_name in key_properties:
                mdata = write(
                    mdata, ("properties", field_name), "inclusion", "automatic"
                )
            else:
                mdata = write(
                    mdata, ("properties", field_name), "inclusion", "available"
                )

    return to_list(mdata)
