import { h64 } from "../../../shared/src/hash.js";
import { mapEntries } from "../../../shared/src/objects.js";
import { normalizeClientSchema } from "../../../zero-protocol/src/client-schema.js";
function createSchema(options) {
  const retTables = {};
  const retRelationships = {};
  const serverNames = /* @__PURE__ */ new Set();
  options.tables.forEach((table) => {
    const { serverName = table.schema.name } = table.schema;
    if (serverNames.has(serverName)) {
      throw new Error(`Multiple tables reference the name "${serverName}"`);
    }
    serverNames.add(serverName);
    if (Object.hasOwn(retTables, table.schema.name)) {
      throw new Error(
        `Table "${table.schema.name}" is defined more than once in the schema`
      );
    }
    retTables[table.schema.name] = table.build();
  });
  options.relationships?.forEach((relationships) => {
    if (retRelationships[relationships.name]) {
      throw new Error(
        `Relationships for table "${relationships.name}" are defined more than once in the schema`
      );
    }
    retRelationships[relationships.name] = relationships.relationships;
    checkRelationship(
      relationships.relationships,
      relationships.name,
      retTables
    );
  });
  return {
    tables: retTables,
    relationships: retRelationships,
    enableLegacyQueries: options.enableLegacyQueries,
    enableLegacyMutators: options.enableLegacyMutators
  };
}
function checkRelationship(relationships, tableName, tables) {
  Object.entries(relationships).forEach(([name, rel]) => {
    let source = tables[tableName];
    if (source.columns[name] !== void 0) {
      throw new Error(
        `Relationship "${tableName}"."${name}" cannot have the same name as the column "${name}" on the the table "${source.name}"`
      );
    }
    rel.forEach((connection) => {
      if (!tables[connection.destSchema]) {
        throw new Error(
          `For relationship "${tableName}"."${name}", destination table "${connection.destSchema}" is missing in the schema`
        );
      }
      if (!source.columns[connection.sourceField[0]]) {
        throw new Error(
          `For relationship "${tableName}"."${name}", the source field "${connection.sourceField[0]}" is missing in the table schema "${source.name}"`
        );
      }
      source = tables[connection.destSchema];
    });
  });
}
function clientSchemaFrom(schema) {
  const client = {
    tables: mapEntries(
      schema.tables,
      (name, { serverName, columns, primaryKey }) => [
        serverName ?? name,
        {
          columns: mapEntries(columns, (name2, { serverName: serverName2, type }) => [
            serverName2 ?? name2,
            { type }
          ]),
          primaryKey: primaryKey.map((k) => columns[k].serverName ?? k)
        }
      ]
    )
  };
  const clientSchema = normalizeClientSchema(client);
  const hash = h64(JSON.stringify(clientSchema)).toString(36);
  return { clientSchema, hash };
}
export {
  clientSchemaFrom,
  createSchema
};
//# sourceMappingURL=schema-builder.js.map
