// Copyright (c) Jupyter Development Team.
// Distributed under the terms of the Modified BSD License.

const childProcess = require('child_process');
const json2ts = require('json-schema-to-typescript');
const fs = require('fs');
const prettier = require('prettier');

const SCHEMA_PATH = 'src/schema.ts';
const PLUGIN_PATH = 'src/plugin.ts';

async function generateInterface(schemaPath, filepath) {
  const bannerComment =
    '// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\n\n/* eslint-disable */ \n/**\n* This file was automatically generated by json-schema-to-typescript.\n* DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,\n* and run jlpm build:schema to regenerate this file.\n*/';
  const prettierConfig = {
    singleQuote: true,
    trailingComma: 'none',
    arrowParens: 'avoid'
  };

  const content = await json2ts.compileFromFile(schemaPath, {
    unreachableDefinitions: true,
    bannerComment,
    format: true,
    style: {
      singleQuote: true
    }
  });

  const formatted = prettier.format(content, {
    ...prettierConfig,
    filepath
  });
  return formatted;
}

function getSchemaPath() {
  const serverPackage = 'jupyter_lsp';
  const schemaLocalPath = 'schema/schema.json';

  const cmd = `python -c '
try:
    from importlib.resources import files
except ImportError:
    from importlib_resources import files
print(files("${serverPackage}")/ "${schemaLocalPath}")
  '`;
  let schemaPath;
  try {
    const value = childProcess.execSync(cmd, {});
    schemaPath = value
      .toString()
      .replace(/(\r\n|\n)$/, '')
      .trim();
  } catch {
    schemaPath = null;
  }
  const pluginPath = '../lsp-extension/schema/plugin.json';
  return { schemaPath, pluginPath };
}

function generateFile() {
  const { schemaPath, pluginPath } = getSchemaPath();
  let schemaContent = Promise.resolve(`
  export type LanguageServerSession = any;
  export type LanguageServerSpec = any;
  export type ServerSpecProperties = any;
    `);
  if (schemaPath) {
    schemaContent = generateInterface(schemaPath, SCHEMA_PATH);
  }
  let pluginContent = Promise.resolve(`
  export type LanguageServer2 = any;
  export type AskServersToSendTraceNotifications = any;
    `);
  if (pluginPath) {
    pluginContent = generateInterface(pluginPath, PLUGIN_PATH);
  }
  return { schemaContent, pluginContent };
}

function writeFile() {
  const { schemaContent, pluginContent } = generateFile();
  pluginContent.then(content => fs.writeFileSync(PLUGIN_PATH, content));
  schemaContent.then(content => fs.writeFileSync(SCHEMA_PATH, content));
}

async function verifyFile() {
  const { schemaContent, pluginContent } = generateFile();
  const currentSchema = fs.readFileSync(SCHEMA_PATH).toString();
  const currentPlugin = fs.readFileSync(PLUGIN_PATH).toString();
  const schemaContentString = await schemaContent;
  const pluginContentString = await pluginContent;

  return (
    currentSchema === schemaContentString &&
    currentPlugin === pluginContentString
  );
}

if (require.main === module) {
  const args = process.argv.slice(2);
  if (args.length === 0) {
    writeFile();
  } else if (args[0] === 'check') {
    verifyFile().then(ret => {
      console.log(ret);
    });
  }
}
