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/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()
