/** Type guard that checks whether a string is a recognised {@link Metadata} field name. */
export const isMetadataKey = (key) => {
    return key === 'colors';
};
/**
 * Extracts typed {@link Metadata} from a proto `Struct` fields map.
 *
 * The `colors` field is expected as a base64-encoded string (the only way to
 * represent binary data in a `google.protobuf.Value`), which is decoded into
 * a `Uint8Array`.
 *
 * Unknown keys are silently ignored.
 */
export const parseMetadata = (fields = {}) => {
    const json = {};
    for (const [k, v] of Object.entries(fields)) {
        if (!isMetadataKey(k))
            continue;
        const unwrappedValue = unwrapValue(v);
        switch (k) {
            case 'colors': {
                if (typeof unwrappedValue === 'string') {
                    const binary = atob(unwrappedValue);
                    const colorBytes = new Uint8Array(binary.length);
                    for (let i = 0; i < binary.length; i++) {
                        colorBytes[i] = binary.charCodeAt(i);
                    }
                    json.colors = colorBytes;
                }
                break;
            }
        }
    }
    return json;
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const unwrapValue = (value) => {
    if (!value?.kind)
        return value;
    switch (value.kind.case) {
        case 'numberValue':
        case 'stringValue':
        case 'boolValue': {
            return value.kind.value;
        }
        case 'structValue': {
            const result = {};
            for (const [key, val] of Object.entries(value.kind.value.fields || {})) {
                // eslint-disable-next-line @typescript-eslint/no-explicit-any
                result[key] = unwrapValue(val);
            }
            return result;
        }
        case 'listValue': {
            return (value.kind.value.values?.map(
            // eslint-disable-next-line @typescript-eslint/no-explicit-any
            (v) => unwrapValue(v)) || []);
        }
        case 'nullValue': {
            return null;
        }
        default: {
            return value.kind.value;
        }
    }
};
