import set from 'lodash/fp/set.js';
import mapValues from 'lodash/mapValues.js';
function $refToPath(ref) {
    return ref.substr(2).split('/');
}
function $refToShapeName(ref) {
    return $refToPath(ref)[1];
}
function findServiceIdForNamespace(projectSchema, namespace) {
    if (projectSchema.services) {
        for (const [serviceId, service] of Object.entries(projectSchema.services)) {
            if (service.namespace === namespace) {
                return serviceId;
            }
        }
    }
    return 'local';
}
function updateRefSyntax(projectSchema, $ref) {
    const shapeName = $refToShapeName($ref);
    const parts = shapeName.split('_');
    const serviceId = parts.length === 1 ? 'local' : findServiceIdForNamespace(projectSchema, parts[0]);
    return `${serviceId}:${parts[parts.length - 1]}`;
}
function migrateQueryToV3_10(projectSchema) {
    return (query, queryName) => {
        const { args, shape } = query;
        if (typeof args === 'object' && ('oneOf' in args || 'allOf' in args || '$ref' in args || '@ref' in args)) {
            // As of 11/15/2021 no production schemas contained queries with these args
            throw new Error(`Query "${queryName}" contains an unsupported arg schema ${JSON.stringify(args)}. Please contact support`);
        }
        if (typeof shape === 'object') {
            if (shape.items.$ref) {
                return set('shape.items', { '@ref': updateRefSyntax(projectSchema, shape.items.$ref) }, query);
            }
            if (!shape.items['@ref']) {
                // As of 11/15/2021 no production schemas contained queries with array return shapes that are not @refs
                throw new Error(`Query "${queryName}" contains an unsupported shape schema ${JSON.stringify(shape)}. Please contact support`);
            }
        }
        return query;
    };
}
function migrateShapeToV3_10(shape) {
    const { schema, ...rest } = shape;
    // As of 11/15/2021 no production schemas contained shapes with array schemas
    if ('type' in schema && schema.type === 'array') {
        throw new Error(`Shape ${shape.name} uses an unsupported array schema. Please contact support`);
    }
    const newSchema = '$ref' in schema || '@ref' in schema ? { allOf: [schema] } : schema;
    return {
        ...rest,
        schema: newSchema
    };
}
const migrate = async (_, projectSchema) => {
    const { queries, mutations, shapes, schemaVersion, ...rest } = projectSchema;
    const migrate = migrateQueryToV3_10(projectSchema);
    return {
        ...rest,
        queries: mapValues(queries, migrate),
        mutations: mapValues(mutations, migrate),
        shapes: mapValues(shapes, migrateShapeToV3_10),
        schemaVersion: '3.10.0'
    };
};
export default migrate;
