import * as fs from 'fs';
import * as ts from 'typescript';

// generate tsclient.go and tsserver.go, which are the definitions and stubs for
// supporting the LPS protocol. These files have 3 sections:
// 1. define the Client or Server type
// 2. fill out the clientHandler or serveHandler which is basically a large
//    switch on the requests and notifications received by the client/server.
// 3. The methods corresponding to these. (basically parse the request,
//    call something, and perhaps send a response.)

let dir = process.env['HOME'];
let fnames = [
  `/vscode-languageserver-node/protocol/src/protocol.ts`,
  `/vscode-languageserver-node/jsonrpc/src/main.ts`
];

let fda: number, fdy: number;  // file descriptors

function createOutputFiles() {
  fda = fs.openSync('/tmp/ts-a', 'w')  // dump of AST
  fdy = fs.openSync('/tmp/ts-c', 'w')  // unused, for debugging
}
function pra(s: string) {
  return (fs.writeSync(fda, s))
}
function prb(s: string) {
  return (fs.writeSync(fdy, s + '\n'))
}

let program: ts.Program;
function generate(files: string[], options: ts.CompilerOptions): void {
  program = ts.createProgram(files, options);
  program.getTypeChecker();

  dumpAST();  // for debugging

  // visit every sourceFile in the program, collecting information
  for (const sourceFile of program.getSourceFiles()) {
    if (!sourceFile.isDeclarationFile) {
      ts.forEachChild(sourceFile, genStuff)
    }
  }
  // when 4 args, they are param, result, error, registration options, e.g.:
  // RequestType<TextDocumentPositionParams, Definition | DefinitionLink[] |
  // null,
  //   void, TextDocumentRegistrationOptions>('textDocument/implementation');
  // 3 args is RequestType0('shutdown')<void, void, void>
  // and RequestType0('workspace/workspaceFolders)<WorkspaceFolder[]|null, void,
  // void>

  // the two args are the notification data and the registration data
  // except for textDocument/selectionRange and a NotificationType0('exit')
  // selectionRange is the following, but for now do it by hand, special case.
  // RequestType<TextDocumentPositionParams, SelectionRange[] | null, any, any>
  //    = new RequestType('textDocument/selectionRange')
  // and foldingRange has the same problem.

  setReceives();  // distinguish client and server
  // for each of Client and Server there are 3 parts to the output:
  // 1. type X interface {methods}
  // 2. func (h *serverHandler) Deliver(...) { switch r.method }
  // 3. func (x *xDispatcher) Method(ctx, parm)
  not.forEach(
    (v, k) => {
      receives.get(k) == 'client' ? goNot(client, k) :
        goNot(server, k)
    });
  req.forEach(
    (v, k) => {
      receives.get(k) == 'client' ? goReq(client, k) :
        goReq(server, k)
    });
  // and print the Go code
  output(client);
  output(server);
  return;
}

// Go signatures for methods.
function sig(nm: string, a: string, b: string, names?: boolean): string {
  if (a != '') {
    if (names)
      a = ', params *' + a;
    else
      a = ', *' + a;
  }
  let ret = 'error';
  if (b != '') {
    b.startsWith('[]') || b.startsWith('interface') || (b = '*' + b);
    ret = `(${b}, error)`;
  }
  let start = `${nm}(`;
  if (names) {
    start = start + 'ctx ';
  }
  return `${start}context.Context${a}) ${ret}`;
}

const notNil = `if r.Params != nil {
				r.Reply(ctx, nil, jsonrpc2.NewErrorf(jsonrpc2.CodeInvalidParams, "Expected no params"))
				return true
			}`;
// Go code for notifications. Side is client or server, m is the request method
function goNot(side: side, m: string) {
  const n = not.get(m);
  let a = goType(m, n.typeArguments[0]);
  // let b = goType(m, n.typeArguments[1]); These are registration options
  const nm = methodName(m);
  side.methods.push(sig(nm, a, ''));
  const caseHdr = `case "${m}": // notif`;
  let case1 = notNil;
  if (a != '') {
    case1 = `var params ${a}
    if err := json.Unmarshal(*r.Params, &params); err != nil {
      sendParseError(ctx, r, err)
      return true
    }
    if err := h.${side.name}.${nm}(ctx, &params); err != nil {
      log.Error(ctx, "", err)
    }
    return true`;
  } else {
    case1 = `if err := h.${side.name}.${nm}(ctx); err != nil {
      log.Error(ctx, "", err)
    }
    return true`;
  }
  side.cases.push(`${caseHdr}\n${case1}`);

  const arg3 = a == '' ? 'nil' : 'params';
  side.calls.push(`
  func (s *${side.name}Dispatcher) ${sig(nm, a, '', true)} {
    return s.Conn.Notify(ctx, "${m}", ${arg3})
  }`);
}

// Go code for requests.
function goReq(side: side, m: string) {
  const n = req.get(m);

  const nm = methodName(m);
  let a = goType(m, n.typeArguments[0]);
  let b = goType(m, n.typeArguments[1]);
  if (n.getText().includes('Type0')) {
    b = a;
    a = '';  // workspace/workspaceFolders and shutdown
  }
  prb(`${side.name} req ${a != ''},${b != ''} ${nm} ${m} ${loc(n)}`)
  side.methods.push(sig(nm, a, b));

  const caseHdr = `case "${m}": // req`;
  let case1 = notNil;
  if (a != '') {
    case1 = `var params ${a}
    if err := json.Unmarshal(*r.Params, &params); err != nil {
      sendParseError(ctx, r, err)
      return true
    }`;
  }
  const arg2 = a == '' ? '' : ', &params';
  let case2 = `if err := h.${side.name}.${nm}(ctx${arg2}); err != nil {
    log.Error(ctx, "", err)
  }`;
  if (b != '') {
    case2 = `resp, err := h.${side.name}.${nm}(ctx${arg2})
    if err := r.Reply(ctx, resp, err); err != nil {
      log.Error(ctx, "", err)
    }
    return true`;
  } else {  // response is nil
    case2 = `err := h.${side.name}.${nm}(ctx${arg2})
    if err := r.Reply(ctx, nil, err); err != nil {
      log.Error(ctx, "", err)
    }
    return true`
  }

  side.cases.push(`${caseHdr}\n${case1}\n${case2}`);

  const callHdr = `func (s *${side.name}Dispatcher) ${sig(nm, a, b, true)} {`;
  let callBody = `return s.Conn.Call(ctx, "${m}", nil, nil)\n}`;
  if (b != '') {
    const p2 = a == '' ? 'nil' : 'params';
    let theRet = `result`;
    !b.startsWith('[]') && !b.startsWith('interface') && (theRet = '&result');
    callBody = `var result ${b}
			if err := s.Conn.Call(ctx, "${m}", ${
      p2}, &result); err != nil {
				return nil, err
      }
      return ${theRet}, nil
    }`;
  } else if (a != '') {
    callBody = `return s.Conn.Call(ctx, "${m}", params, nil) // Call, not Notify
  }`
  }
  side.calls.push(`${callHdr}\n${callBody}\n`);
}

// make sure method names are unique
let seenNames = new Set<string>();
function methodName(m: string): string {
  const i = m.indexOf('/');
  let s = m.substring(i + 1);
  let x = s[0].toUpperCase() + s.substring(1);
  if (seenNames.has(x)) {
    x += m[0].toUpperCase() + m.substring(1, i);
  }
  seenNames.add(x);
  return x;
}

function output(side: side) {
  if (side.outputFile === undefined) side.outputFile = `ts${side.name}.go`;
  side.fd = fs.openSync(side.outputFile, 'w');
  const f = function (s: string) {
    fs.writeSync(side.fd, s);
    fs.writeSync(side.fd, '\n');
  };
  f(`package protocol`);
  f(`// Code generated (see typescript/README.md) DO NOT EDIT.\n`);
  f(`
  import (
    "context"
    "encoding/json"

    "golang.org/x/tools/internal/jsonrpc2"
    "golang.org/x/tools/internal/lsp/telemetry/log"
  )
  `);
  const a = side.name[0].toUpperCase() + side.name.substring(1)
  f(`type ${a} interface {`);
  side.methods.forEach((v) => { f(v) });
  f('}\n');
  f(`func (h ${side.name}Handler) Deliver(ctx context.Context, r *jsonrpc2.Request, delivered bool) bool {
      if delivered {
        return false
      }
      switch r.Method {
      case "$/cancelRequest":
        var params CancelParams
        if err := json.Unmarshal(*r.Params, &params); err != nil {
          sendParseError(ctx, r, err)
          return true
        }
        r.Conn().Cancel(params.ID)
        return true`);
  side.cases.forEach((v) => { f(v) });
  f(`
  default:
    return false
  }
}`);
  f(`
  type ${side.name}Dispatcher struct {
    *jsonrpc2.Conn
  }
  `);
  side.calls.forEach((v) => { f(v) });
  if (side.name == 'server')
    f(`
  type CancelParams struct {
    /**
     * The request id to cancel.
     */
    ID jsonrpc2.ID \`json:"id"\`
  }`);
}

interface side {
  methods: string[];
  cases: string[];
  calls: string[];
  name: string;    // client or server
  goName: string;  // Client or Server
  outputFile?: string;
  fd?: number
}
let client: side =
  { methods: [], cases: [], calls: [], name: 'client', goName: 'Client' };
let server: side =
  { methods: [], cases: [], calls: [], name: 'server', goName: 'Server' };

let req = new Map<string, ts.NewExpression>();        // requests
let not = new Map<string, ts.NewExpression>();        // notifications
let receives = new Map<string, 'server' | 'client'>();  // who receives it

function setReceives() {
  // mark them all as server, then adjust the client ones.
  // it would be nice to have some independent check
  req.forEach((_, k) => { receives.set(k, 'server') });
  not.forEach((_, k) => { receives.set(k, 'server') });
  receives.set('window/logMessage', 'client');
  receives.set('telemetry/event', 'client');
  receives.set('client/registerCapability', 'client');
  receives.set('client/unregisterCapability', 'client');
  receives.set('window/showMessage', 'client');
  receives.set('window/showMessageRequest', 'client');
  receives.set('workspace/workspaceFolders', 'client');
  receives.set('workspace/configuration', 'client');
  receives.set('workspace/applyEdit', 'client');
  receives.set('textDocument/publishDiagnostics', 'client');
  // a small check
  receives.forEach((_, k) => {
    if (!req.get(k) && !not.get(k)) throw new Error(`missing ${k}}`);
    if (req.get(k) && not.get(k)) throw new Error(`dup ${k}`);
  })
}

function goType(m: string, n: ts.Node): string {
  if (n === undefined) return '';
  if (ts.isTypeReferenceNode(n)) return n.typeName.getText();
  if (n.kind == ts.SyntaxKind.VoidKeyword) return '';
  if (n.kind == ts.SyntaxKind.AnyKeyword) return 'interface{}';
  if (ts.isArrayTypeNode(n)) return '[]' + goType(m, n.elementType);
  // special cases, before we get confused
  switch (m) {
    case 'textDocument/completion':
      return 'CompletionList';
    case 'textDocument/documentSymbol':
      return '[]DocumentSymbol';
    case 'textDocument/prepareRename':
      return 'Range';
    case 'textDocument/codeAction':
      return '[]CodeAction';
  }
  if (ts.isUnionTypeNode(n)) {
    let x: string[] = [];
    n.types.forEach(
      (v) => { v.kind != ts.SyntaxKind.NullKeyword && x.push(goType(m, v)) });
    if (x.length == 1) return x[0];

    prb(`===========${m} ${x}`)
    // Because we don't fully resolve types, we don't know that
    // Definition is Location | Location[]
    if (x[0] == 'Definition') return '[]Location';
    if (x[1] == '[]' + x[0] + 'Link') return x[1];
    throw new Error(`${m}, ${x} unexpected types`)
  }
  return '?';
}

// walk the AST finding Requests and Notifications
function genStuff(node: ts.Node) {
  if (!ts.isNewExpression(node)) {
    ts.forEachChild(node, genStuff)
    return;
  }
  // process the right kind of new expression
  const wh = node.expression.getText();
  if (wh != 'RequestType' && wh != 'RequestType0' && wh != 'NotificationType' &&
    wh != 'NotificationType0')
    return;
  if (node.arguments === undefined || node.arguments.length != 1 ||
    !ts.isStringLiteral(node.arguments[0])) {
    throw new Error(`missing n.arguments ${loc(node)}`)
  }
  // RequestType<useful>=new RequestTYpe('foo')
  if (node.typeArguments === undefined) {
    node.typeArguments = lookUp(node);
  }
  // new RequestType<useful>
  let s = node.arguments[0].getText();
  // Request or Notification
  const v = wh[0] == 'R' ? req : not;
  s = s.substring(1, s.length - 1);    // remove quoting
  if (s == '$/cancelRequest') return;  // special case in output
  v.set(s, node);
}

function lookUp(n: ts.NewExpression): ts.NodeArray<ts.TypeNode> {
  // parent should be VariableDeclaration. its children should be
  // Identifier('type') ???
  // TypeReference: [Identifier('RequestType1), ]
  // NewExpression (us)
  const p = n.parent;
  if (!ts.isVariableDeclaration(p)) throw new Error(`not variable decl`);
  const tr = p.type;
  if (!ts.isTypeReferenceNode(tr)) throw new Error(`not TypeReference`);
  return tr.typeArguments;
}

function dumpAST() {
  // dump the ast, for debugging
  for (const sourceFile of program.getSourceFiles()) {
    if (!sourceFile.isDeclarationFile) {
      // walk the tree to do stuff
      ts.forEachChild(sourceFile, describe);
    }
  }
}

// some tokens have the wrong default name
function strKind(n: ts.Node): string {
  const x = ts.SyntaxKind[n.kind];
  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';
  }
}

function describe(node: ts.Node) {
  if (node === undefined) {
    return
  }
  let indent = '';

  function f(n: ts.Node) {
    if (ts.isIdentifier(n)) {
      pra(`${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
      pra(`${indent} ${loc(n)} ${strKind(n)} ${m.length} \n`)
    } else {
      pra(`${indent} ${loc(n)} ${strKind(n)} \n`)
    };
    indent += '  '
    ts.forEachChild(n, f)
    indent = indent.slice(0, indent.length - 2)
  }
  f(node)
}

// string version of the location in the source file
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})`
}

// ad hoc argument parsing: [-d dir] [-o outputfile], and order matters
function main() {
  let args = process.argv.slice(2)  // effective command line
  if (args.length > 0) {
    let j = 0;
    if (args[j] == '-d') {
      dir = args[j + 1]
      j += 2
    }
    if (j != args.length) throw new Error(`incomprehensible args ${args}`)
  }
  let files: string[] = [];
  for (let i = 0; i < fnames.length; i++) {
    files.push(`${dir}${fnames[i]}`)
  }
  createOutputFiles()
  generate(
    files, { target: ts.ScriptTarget.ES5, module: ts.ModuleKind.CommonJS });
}

main()
