import { relative } from 'node:path';
import { relativeDirectoryForDisplay, format } from '../shared.mjs';

const ENDS_WITH_TSCONFIG = /[/]?tsconfig[.a-z0-9]*[.]json/i;
async function addToTsConfig(directory, output) {
  const tsconfig = JSON.parse(await output.read('tsconfig.json'));
  tsconfig.references ??= [];
  const relativePath = relative(output.root, directory);
  const relativeForDisplay = relativeDirectoryForDisplay(relativePath);
  if (tsconfig.references.length === 0) {
    tsconfig.references.push({
      path: relativeForDisplay
    });
  } else {
    let hasExistingReference = false;
    let referenceFormat = 'pretty-relative';
    for (const {
      path
    } of tsconfig.references) {
      if (path.startsWith('./')) {
        if (ENDS_WITH_TSCONFIG.test(path)) {
          referenceFormat = 'pretty-tsconfig';
          if (path === `${relativeForDisplay}/tsconfig.json`) {
            hasExistingReference = true;
            break;
          }
        }
        referenceFormat = 'pretty-relative';
        if (path === relativeForDisplay) {
          hasExistingReference = true;
          break;
        }
      } else if (ENDS_WITH_TSCONFIG.test(path)) {
        referenceFormat = 'tsconfig';
        if (path === `${relativePath}/tsconfig.json`) {
          hasExistingReference = true;
          break;
        }
      } else {
        referenceFormat = 'relative';
        if (path === relativePath) {
          hasExistingReference = true;
          break;
        }
      }
    }
    if (!hasExistingReference) {
      let path;
      if (referenceFormat === 'pretty-tsconfig') {
        path = `${relativeForDisplay}/tsconfig.json`;
      } else if (referenceFormat === 'pretty-relative') {
        path = relativeForDisplay;
      } else if (referenceFormat === 'tsconfig') {
        path = `${relativePath}/tsconfig.json`;
      } else {
        path = relativePath;
      }
      tsconfig.references.push({
        path
      });
    }
  }
  tsconfig.references = tsconfig.references.sort(({
    path: pathOne
  }, {
    path: pathTwo
  }) => pathOne.localeCompare(pathTwo));
  await output.write('tsconfig.json', await format(JSON.stringify(tsconfig), {
    as: 'json'
  }));
}

export { addToTsConfig };
