import * as path from 'path';
/* tslint:disable:no-require-imports */
const protobufjs = require('protobufjs');
// tslint:disable-next-line:variable-name: ByteBuffer is instantiatable.
const ByteBuffer = require('bytebuffer');

export const DEBUG = false;

export function debug(...args: Array<{}>) {
  if (DEBUG) console.error.apply(console, args);
}

/**
 * Write a message to stderr, which appears in the bazel log and is visible to
 * the end user.
 */
export function log(...args: Array<{}>) {
  console.error.apply(console, args);
}

export function runAsWorker(args: string[]) {
  return args.indexOf('--persistent_worker') !== -1;
}

const workerpb = (function loadWorkerPb() {
  const protoPath = '../worker_protocol.proto';

  // Use node module resolution so we can find the .proto file in any of the root dirs
  let protofile;
  try {
    // Look for the .proto file relative in its @bazel/typescript npm package
    // location
    protofile = require.resolve(protoPath);
  } catch (e) {
  }
  if (!protofile) {
    // If not found above, look for the .proto file in its rules_typescript
    // workspace location
    // This extra lookup should never happen in google3. It's only needed for
    // local development in the rules_typescript repo.
    protofile = require.resolve(
        '../../third_party/github.com/bazelbuild/bazel/src/main/protobuf/worker_protocol.proto');
  }

  // Under Bazel, we use the version of TypeScript installed in the user's
  // workspace This means we also use their version of protobuf.js. Handle both.
  // v5 and v6 by checking which one is present.
  if (protobufjs.loadProtoFile) {
    // Protobuf.js v5
    const protoNamespace = protobufjs.loadProtoFile(protofile);
    if (!protoNamespace) {
      throw new Error('Cannot find ' + path.resolve(protoPath));
    }
    return protoNamespace.build('blaze.worker');
  } else {
    // Protobuf.js v6
    const protoNamespace = protobufjs.loadSync(protofile);
    if (!protoNamespace) {
      throw new Error('Cannot find ' + path.resolve(protoPath));
    }
    return protoNamespace.lookup('blaze.worker');
  }
})();

interface Input {
  getPath(): string;
  getDigest(): {toString(encoding: string): string};  // npm:ByteBuffer
}
interface WorkRequest {
  getArguments(): string[];
  getInputs(): Input[];
}

export function runWorkerLoop(
    runOneBuild: (args: string[], inputs?: {[path: string]: string}) =>
        boolean) {
  // Hook all output to stderr and write it to a buffer, then include
  // that buffer's in the worker protcol proto's textual output.  This
  // means you can log via console.error() and it will appear to the
  // user as expected.
  let consoleOutput = '';
  process.stderr.write =
      (chunk: string | Buffer, ...otherArgs: any[]): boolean => {
        consoleOutput += chunk.toString();
        return true;
      };

  // Accumulator for asynchronously read input.
  // tslint:disable-next-line:no-any protobufjs is untyped
  let buf: any;
  process.stdin.on('readable', () => {
    const chunk = process.stdin.read();
    if (!chunk) return;

    const wrapped = ByteBuffer.wrap(chunk);
    buf = buf ? ByteBuffer.concat([buf, wrapped]) : wrapped;
    try {
      let req: WorkRequest;
      // Read all requests that have accumulated in the buffer.
      while ((req = workerpb.WorkRequest.decodeDelimited(buf)) != null) {
        debug('=== Handling new build request');
        // Reset accumulated log output.
        consoleOutput = '';
        const args = req.getArguments();
        const inputs: {[path: string]: string} = {};
        for (const input of req.getInputs()) {
          inputs[input.getPath()] = input.getDigest().toString('hex');
        }
        debug('Compiling with:\n\t' + args.join('\n\t'));
        const exitCode = runOneBuild(args, inputs) ? 0 : 1;
        process.stdout.write(new workerpb.WorkResponse()
                                 .setExitCode(exitCode)
                                 .setOutput(consoleOutput)
                                 .encodeDelimited()
                                 .toBuffer());
        // Force a garbage collection pass.  This keeps our memory usage
        // consistent across multiple compilations, and allows the file
        // cache to use the current memory usage as a guideline for expiring
        // data.  Note: this is intentionally not within runOneBuild(), as
        // we want to gc only after all its locals have gone out of scope.
        global.gc();
      }
      // Avoid growing the buffer indefinitely.
      buf.compact();
    } catch (e) {
      log('Compilation failed', e.stack);
      process.stdout.write(new workerpb.WorkResponse()
                               .setExitCode(1)
                               .setOutput(consoleOutput)
                               .encodeDelimited()
                               .toBuffer());
      // Clear buffer so the next build won't read an incomplete request.
      buf = null;
    }
  });
}
