/* eslint-disable */
/**
 * This file was automatically generated by scripts/manifest/deserialize-ts.mustache.
 * DO NOT MODIFY IT BY HAND. Instead, modify scripts/manifest/deserialize-ts.mustache,
 * and run node ./scripts/manifest/generateFormatTypes.js to regenerate this file.
 */

import {
  {{type}},
  Any{{type}},
  migrate{{type}},
  validate{{type}},
  latest{{type}}Format,
} from ".";
import { DeserializeManifestOptions } from "../../";

import * as Semver from "semver";
import YAML from "yaml";

export function deserialize{{type}}(
  manifest: string,
  options?: DeserializeManifestOptions
): {{type}} {
  let any{{type}}: Any{{type}} | undefined;
  try {
    any{{type}} = JSON.parse(manifest) as Any{{type}};
  } catch (_) {
    try {
      any{{type}} = YAML.parse(manifest) as Any{{type}};
    } catch (_) { }
  }

  if (!any{{type}}) {
    throw Error(`Unable to parse {{type}}: ${manifest}`);
  }

  if (!options || !options.noValidate) {
    validate{{type}}(any{{type}}, options?.extSchema);
  }

  any{{type}}.__type = "{{type}}";

  const versionCompare = Semver.compare(
    Semver.coerce(any{{type}}.format) || any{{type}}.format,
    Semver.coerce(latest{{type}}Format) || latest{{type}}Format
  );

  if (versionCompare === -1) {
    // Warn user to migrate their manifest
    options?.logger?.warn(`{{type}} is using an older version of the manifest format (${any{{type}}.format}). Please update your manifest to the latest version (${latest{{type}}Format}) by using the "polywrap manifest migrate <type>" command.`);

    // Upgrade
    return migrate{{type}}(any{{type}}, latest{{type}}Format, options?.logger);
  } else if (versionCompare === 1) {
    // Downgrade
    throw Error(
      `Cannot downgrade Polywrap version ${any{{type}}.format}, please upgrade your PolywrapClient package.`
    );
  } else {
    // Latest
    return any{{type}} as {{type}};
  }
}
