/**
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 *
 * @format
 */

'use strict';

const assert = require('assert');
const fs = require('fs');
const yargs = require('yargs');
const argv = yargs
  .option('p', {
    alias: 'platform',
    type: 'string',
    demandOption: true,
  })
  .option('o', {
    alias: 'output',
  })
  .option('s', {
    alias: 'schema-query',
  })
  .parseSync();
const platform = argv.platform.toLowerCase();
const output = argv.output;
const schemaQuery = argv.s;
if (!['ios', 'android'].includes(platform)) {
  throw new Error(`Invalid platform ${platform}`);
}
if (!schemaQuery.startsWith('@')) {
  throw new Error(
    "The argument provided to --schema-query must be a filename that starts with '@'.",
  );
}
const schemaQueryOutputFile = schemaQuery.replace(/^@/, '');
const schemaQueryOutput = fs.readFileSync(schemaQueryOutputFile, 'utf8');
const modules = {};
const specNameToFile = {};
const schemaFiles =
  schemaQueryOutput.length > 0 ? schemaQueryOutput.split(' ') : [];
for (const file of schemaFiles) {
  const schema = JSON.parse(fs.readFileSync(file, 'utf8'));
  if (schema.modules) {
    for (const specName in schema.modules) {
      var _module$excludedPlatf;
      const module = schema.modules[specName];
      if (modules[specName]) {
        assert.deepEqual(
          module,
          modules[specName],
          `App contained two specs with the same file name '${specName}'. Schemas: ${specNameToFile[specName]}, ${file}. Please rename one of the specs.`,
        );
      }
      const excludedPlatforms =
        (_module$excludedPlatf = module.excludedPlatforms) === null ||
        _module$excludedPlatf === void 0
          ? void 0
          : _module$excludedPlatf.map(excludedPlatform =>
              excludedPlatform.toLowerCase(),
            );
      if (excludedPlatforms != null) {
        const cxxOnlyModule =
          excludedPlatforms.includes('ios') &&
          excludedPlatforms.includes('android');
        if (!cxxOnlyModule && excludedPlatforms.includes(platform)) {
          continue;
        }
      }
      if (module.type === 'Component') {
        const components = module.components || {};
        const isExcludedForPlatform = Object.values(components).some(
          component => {
            var _component$excludedPl;
            return (_component$excludedPl = component.excludedPlatforms) ===
              null || _component$excludedPl === void 0
              ? void 0
              : _component$excludedPl
                  .map(p => p.toLowerCase())
                  .includes(platform);
          },
        );
        if (isExcludedForPlatform) {
          continue;
        }
      }
      if (
        module.type === 'Component' &&
        schema.libraryName === 'FBReactNativeSpec'
      ) {
        continue;
      } else {
        modules[specName] = module;
        specNameToFile[specName] = file;
      }
    }
  }
}
fs.writeFileSync(
  output,
  JSON.stringify({
    modules,
  }),
);
