
// for us typescript ignorati, having an import makes this file a module
import * as fs from 'fs';
import * as ts from 'typescript';

// This file contains various utilities having to do with producing strings
// and managing output

// ------ create files
let dir = process.env['HOME'];
const srcDir = '/vscode-languageserver-node'
export const fnames = [
  `${dir}${srcDir}/protocol/src/common/protocol.ts`,
  `${dir}/${srcDir}/protocol/src/browser/main.ts`, `${dir}${srcDir}/types/src/main.ts`,
  `${dir}${srcDir}/jsonrpc/src/node/main.ts`
];
export const gitHash = '60a5a7825e6f54f57917091f394fd8db7d1724bc'
let outFname = 'tsprotocol.go';
let fda: number, fdb: number, fde: number;  // file descriptors

export function createOutputFiles() {
  fda = fs.openSync('/tmp/ts-a', 'w')  // dump of AST
  fdb = fs.openSync('/tmp/ts-b', 'w')  // unused, for debugging
  fde = fs.openSync(outFname, 'w')     // generated Go
}
export function pra(s: string) {
  return (fs.writeSync(fda, s))
}
export function prb(s: string) {
  return (fs.writeSync(fdb, s))
}
export function prgo(s: string) {
  return (fs.writeSync(fde, s))
}

// Get the hash value of the git commit
export function git(): string {
  let a = fs.readFileSync(`${dir}${srcDir}/.git/HEAD`).toString();
  // ref: refs/heads/foo, or a hash like
  // cc12d1a1c7df935012cdef5d085cdba04a7c8ebe
  if (a.charAt(a.length - 1) == '\n') {
    a = a.substring(0, a.length - 1);
  }
  if (a.length == 40) {
    return a  // a hash
  }
  if (a.substring(0, 5) == 'ref: ') {
    const fname = `${dir}${srcDir}/.git/` + a.substring(5);
    let b = fs.readFileSync(fname).toString()
    if (b.length == 41) {
      return b.substring(0, 40);
    }
  }
  throw new Error('failed to find the git commit hash')
}

// Produce a header for Go output files
export function computeHeader(pkgDoc: boolean): string {
  let lastMod = 0
  let lastDate: Date
  for (const f of fnames) {
    const st = fs.statSync(f)
    if (st.mtimeMs > lastMod) {
      lastMod = st.mtimeMs
      lastDate = st.mtime
    }
  }
  const a =
    `// Package protocol contains data types and code for LSP jsonrpcs\n` +
    `// generated automatically from vscode-languageserver-node\n` +
    `// commit: ${gitHash}\n` +
    `// last fetched ${lastDate}\n`
  const b = 'package protocol\n'
  const c = `\n// Code generated (see typescript/README.md) DO NOT EDIT.\n\n`
  if (pkgDoc) {
    return a + b + c
  }
  else {
    return b + a + c
  }
};

// Turn a typescript name into an exportable Go name, and appease lint
export function goName(s: string): string {
  let ans = s
  if (s.charAt(0) == '_') {
    ans = 'Inner' + s.substring(1)
  }
  else { ans = s.substring(0, 1).toUpperCase() + s.substring(1) };
  ans = ans.replace(/Uri$/, 'URI')
  ans = ans.replace(/Id$/, 'ID')
  return ans
}

// Generate JSON tag for a struct field
export function JSON(n: ts.PropertySignature): string {
  const json = `\`json:"${n.name.getText()}${
    n.questionToken != undefined ? ',omitempty' : ''}"\``;
  return json
}

// Generate modifying prefixes and suffixes to ensure
// consts are unique. (Go consts are package-level, but Typescript's are
// not.) Use suffixes to minimize changes to gopls.
export function constName(nm: string, type: string): string {
  let pref = new Map<string, string>([
    ['DiagnosticSeverity', 'Severity'], ['WatchKind', 'Watch'],
    ['SignatureHelpTriggerKind', 'Sig'], ['CompletionItemTag', 'Compl']
  ])  // typeName->prefix
  let suff = new Map<string, string>([
    ['CompletionItemKind', 'Completion'], ['InsertTextFormat', 'TextFormat'],
    ['SymbolTag', 'Symbol']
  ])
  let ans = nm;
  if (pref.get(type)) ans = pref.get(type) + ans;
  if (suff.has(type)) ans = ans + suff.get(type)
  return ans
}

// Find the comments associated with an AST node
export function getComments(node: ts.Node): string {
  const sf = node.getSourceFile();
  const start = node.getStart(sf, false)
  const starta = node.getStart(sf, true)
  const x = sf.text.substring(starta, start)
  return x
}


// --------- printing the AST, for debugging

export function printAST(program: ts.Program) {
  // dump the ast, for debugging
  const f = function (n: ts.Node) {
    describe(n, pra)
  };
  for (const sourceFile of program.getSourceFiles()) {
    if (!sourceFile.isDeclarationFile) {
      // walk the tree to do stuff
      ts.forEachChild(sourceFile, f);
    }
  }
  pra('\n')
  for (const key of Object.keys(seenThings).sort()) {
    pra(`${key}: ${seenThings[key]} \n`)
  }
}

// Used in printing the AST
let seenThings = new Map<string, number>();
function seenAdd(x: string) {
  seenThings[x] = (seenThings[x] === undefined ? 1 : seenThings[x] + 1)
}

function describe(node: ts.Node, pr: (s: string) => any) {
  if (node === undefined) {
    return
  }
  let indent = '';

  function f(n: ts.Node) {
    seenAdd(kinds(n))
    if (ts.isIdentifier(n)) {
      pr(`${indent} ${loc(n)} ${strKind(n)} ${n.text} \n`)
    }
    else if (ts.isPropertySignature(n) || ts.isEnumMember(n)) {
      pra(`${indent} ${loc(n)} ${strKind(n)} \n`)
    }
    else if (ts.isTypeLiteralNode(n)) {
      let m = n.members
      pr(`${indent} ${loc(n)} ${strKind(n)} ${m.length} \n`)
    }
    else if (ts.isStringLiteral(n)) {
      pr(`${indent} ${loc(n)} ${strKind(n)} ${n.text} \n`)
    }
    else { pr(`${indent} ${loc(n)} ${strKind(n)} \n`) };
    indent += ' .'
    ts.forEachChild(n, f)
    indent = indent.slice(0, indent.length - 2)
  }
  f(node)
}


// For debugging, say where an AST node is in a file
export function loc(node: ts.Node): string {
  const sf = node.getSourceFile();
  const start = node.getStart()
  const x = sf.getLineAndCharacterOfPosition(start)
  const full = node.getFullStart()
  const y = sf.getLineAndCharacterOfPosition(full)
  let fn = sf.fileName
  const n = fn.search(/-node./)
  fn = fn.substring(n + 6)
  return `${fn} ${x.line + 1}: ${x.character + 1} (${y.line + 1}: ${
    y.character + 1})`
}
// --- various string stuff

// return a string of the kinds of the immediate descendants
// as part of printing the AST tree
function kinds(n: ts.Node): string {
  let res = 'Seen ' + strKind(n);
  function f(n: ts.Node): void { res += ' ' + strKind(n) };
  ts.forEachChild(n, f)
  return res
}

// What kind of AST node is it? This would just be typescript's
// SyntaxKind[n.kind] except that the default names for some nodes
// are misleading
export function strKind(n: ts.Node): string {
  if (n == null || n == undefined) {
    return 'null'
  }
  const x = ts.SyntaxKind[n.kind];
  // some of these have two names
  switch (x) {
    default:
      return x;
    case 'FirstAssignment':
      return 'EqualsToken';
    case 'FirstBinaryOperator':
      return 'LessThanToken';
    case 'FirstCompoundAssignment':
      return 'PlusEqualsToken';
    case 'FirstContextualKeyword':
      return 'AbstractKeyword';
    case 'FirstLiteralToken':
      return 'NumericLiteral';
    case 'FirstNode':
      return 'QualifiedName';
    case 'FirstTemplateToken':
      return 'NoSubstitutionTemplateLiteral';
    case 'LastTemplateToken':
      return 'TemplateTail';
    case 'FirstTypeNode':
      return 'TypePredicate';
  }
}
