import {
  isDiscriminatorForm,
  isElementsForm,
  isEnumForm,
  isPropertiesForm,
  isRefForm,
  isValuesForm
} from "./json-typedef-js-fork/schema.js";
function jtdToJSONSchema(jtd) {
  const definitions = jtd.definitions ?? {};
  const result = _jtdToJSONSchema(jtd, definitions);
  if (jtd.definitions) {
    result.definitions = Object.fromEntries(
      Object.keys(jtd.definitions ?? {}).map((key) => {
        const value = definitions[key].metadata?.refUnion ? (
          // We want to drop refunion definitions as they are inlined.
          void 0
        ) : _jtdToJSONSchema(definitions[key], definitions);
        return [key, value];
      }).filter(([, value]) => !!value)
    );
  }
  return result;
}
function _jtdToJSONSchema(jtd, definitions, makeOptional) {
  let schema = {};
  if ("type" in jtd) {
    switch (jtd.type) {
      case "string":
      case "timestamp":
        schema.type = "string";
        break;
      case "float32":
      case "float64":
        schema.type = "number";
        break;
      case "int8":
      case "uint8":
      case "int16":
      case "uint16":
      case "int32":
      case "uint32":
        schema.type = "integer";
        break;
      case "boolean":
        schema.type = "boolean";
        break;
      default:
        throw unreachable(jtd.type);
    }
    if (makeOptional) {
    }
  }
  if (isPropertiesForm(jtd)) {
    schema.type = "object";
    schema.properties = {};
    const allProperties = { ...jtd.properties, ...jtd.optionalProperties };
    Object.keys(allProperties).forEach((key) => {
      schema.properties[key] = _jtdToJSONSchema(
        allProperties[key],
        definitions,
        key in (jtd.optionalProperties ?? {})
      );
    });
    schema.required = Object.keys(allProperties ?? {});
    schema.additionalProperties = false;
  }
  if (isElementsForm(jtd)) {
    schema.type = "array";
    schema.items = _jtdToJSONSchema(jtd.elements, definitions);
  }
  if (isValuesForm(jtd)) {
    schema.type = "object";
    schema.additionalProperties = _jtdToJSONSchema(jtd.values, definitions);
  }
  if (isEnumForm(jtd)) {
    schema.type = "string";
    schema.enum = jtd.enum;
  }
  if (jtd.nullable) {
    schema.type = [schema.type, "null"];
  }
  if (isRefForm(jtd)) {
    if (definitions[jtd.ref]?.metadata?.refUnion) {
      schema = _jtdToJSONSchema(definitions[jtd.ref], definitions);
    } else {
      schema.$ref = `#/definitions/${jtd.ref}`;
    }
  }
  if (jtd.metadata?.refUnion && isDiscriminatorForm(jtd)) {
    schema.anyOf = Object.values(jtd.metadata.refUnion).map((ref) => ({
      $ref: `#/definitions/${ref}`
    }));
  } else if (isDiscriminatorForm(jtd)) {
    schema.discriminator = { propertyName: jtd.discriminator };
    schema.oneOf = [];
    Object.keys(jtd.mapping).forEach((value) => {
      const subSchema = _jtdToJSONSchema(jtd.mapping[value], definitions);
      subSchema.properties = subSchema.properties || {};
      subSchema.properties[jtd.discriminator] = { type: "string", enum: [value] };
      subSchema.required = [...subSchema.required || [], jtd.discriminator];
      schema.oneOf.push(subSchema);
    });
  }
  if (jtd.metadata?.description && !schema.$ref) {
  }
  return schema;
}
function unreachable(value) {
  return new Error(`Unreachable: ${value}`);
}
export {
  jtdToJSONSchema
};
//# sourceMappingURL=jtd-to-json-schema.js.map
