// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import "dart:async";
import "dart:convert";
import "dart:io";
import "dart:isolate";
import "dart:mirrors";

import "package:args/args.dart";
import "package:path/path.dart";

/// [Environment] stores gathered arguments information.
class Environment {
  String sdkRoot;
  String pkgRoot;
  var input;
  var output;
  int workers;
  bool prettyPrint;
  bool lcov;
  bool expectMarkers;
  bool verbose;
}

/// [Resolver] resolves imports with respect to a given environment.
class Resolver {
  const DART_PREFIX = "dart:";
  const PACKAGE_PREFIX = "package:";
  const FILE_PREFIX = "file://";
  const HTTP_PREFIX = "http://";

  Map _env;
  List failed = [];

  Resolver(this._env);

  /// Returns the absolute path wrt. to the given environment or null, if the
  /// import could not be resolved.
  resolve(String import) {
    if (import.startsWith(DART_PREFIX)) {
      var slashPos = import.indexOf("/");
      var filePath;
      if (slashPos != -1) {
        var path = import.substring(DART_PREFIX.length, slashPos);
        // Drop patch files, since we don't have their source in the compiled
        // SDK.
        if (path.endsWith("-patch")) {
          failed.add(import);
          return null;
        }
        // Canonicalize path. For instance: _collection-dev => _collection_dev.
        path = path.replaceAll("-", "_");
        filePath = "${_env["sdkRoot"]}"
                   "/${path}${import.substring(slashPos, import.length)}";
      } else {
        // Resolve 'dart:something' to be something/something.dart in the SDK.
        var lib = import.substring(DART_PREFIX.length, import.length);
        filePath = "${_env["sdkRoot"]}/${lib}/${lib}.dart";
      }
      return filePath;
    }
    if (import.startsWith(PACKAGE_PREFIX)) {
      var filePath =
          "${_env["pkgRoot"]}"
          "/${import.substring(PACKAGE_PREFIX.length, import.length)}"; 
      return filePath;
    }
    if (import.startsWith(FILE_PREFIX)) {
      var filePath = fromUri(Uri.parse(import));
      return filePath;
    }
    if (import.startsWith(HTTP_PREFIX)) {
      return import;
    }
    // We cannot deal with anything else.
    failed.add(import);
    return null;
  }
}

/// Converts the given hitmap to lcov format and appends the result to
/// env.output.
///
/// Returns a [Future] that completes as soon as all map entries have been
/// emitted. 
Future lcov(Map hitmap) {
  var emitOne = (key) {
    var v = hitmap[key];
    StringBuffer entry = new StringBuffer();
    entry.write("SF:${key}\n");
    v.keys.toList()
          ..sort()
          ..forEach((k) {
      entry.write("DA:${k},${v[k]}\n");
    });
    entry.write("end_of_record\n");
    env.output.write(entry.toString());
    return new Future.value(null);
  };

  return Future.forEach(hitmap.keys, emitOne);
}

/// Converts the given hitmap to a pretty-print format and appends the result
/// to env.output.
///
/// Returns a [Future] that completes as soon as all map entries have been
/// emitted. 
Future prettyPrint(Map hitMap, List failedLoads) {
  var emitOne = (key) {
    var v = hitMap[key];
    var c = new Completer();
    loadResource(key).then((lines) {
      if (lines == null) {
        failedLoads.add(key);
        c.complete();
        return;
      }
      env.output.write("${key}\n");
      for (var line = 1; line <= lines.length; line++) {
        String prefix = "       ";
        if (v.containsKey(line)) {
          prefix = v[line].toString();
          StringBuffer b = new StringBuffer();
          for (int i = prefix.length; i < 7; i++) {
            b.write(" ");
          }
          b.write(prefix);
          prefix = b.toString();
        }
        env.output.write("${prefix}|${lines[line-1]}\n");
      } 
      c.complete();
    });
    return c.future;
  };

  return Future.forEach(hitMap.keys, emitOne);
}

/// Load an import resource and return a [Future] with a [List] of its lines.
/// Returns [null] instead of a list if the resource could not be loaded.
Future<List> loadResource(String import) {
  if (import.startsWith("http")) {
    Completer c = new Completer();
    HttpClient client = new HttpClient();
    client.getUrl(Uri.parse(import))
        .then((HttpClientRequest request) {
          return request.close();
        })
        .then((HttpClientResponse response) {
          response.transform(new StringDecoder()).toList().then((data) {
            c.complete(data);
            httpClient.close();
          });
        })
        .catchError((e) {
          c.complete(null);
        });
    return c.future;
  } else {
    File f = new File(import);
    return f.readAsLines()
        .catchError((e) {
          return new Future.value(null);
        });
  }
}

/// Creates a single hitmap from a raw json object. Throws away all entries that
/// are not resolvable.
Map createHitmap(String rawJson, Resolver resolver) {
  Map<String, Map<int,int>> hitMap = {};

  addToMap(source, line, count) {
    if (!hitMap[source].containsKey(line)) {
      hitMap[source][line] = 0;
    }
    hitMap[source][line] += count;
  }

  JSON.decode(rawJson).forEach((Map e) {
    String source = resolver.resolve(e["source"]);
    if (source == null) { 
      // Couldnt resolve import, so skip this entry.
      return;
    }
    if (!hitMap.containsKey(source)) {
      hitMap[source] = {};
    }
    var hits = e["hits"];
    // hits is a flat array of the following format:
    // [ <line|linerange>, <hitcount>,...]
    // line: number.
    // linerange: "<line>-<line>".
    for (var i = 0; i < hits.length; i += 2) {
      var k = hits[i];
      if (k is num) {
        // Single line.
        addToMap(source, k, hits[i+1]);
      }
      if (k is String) {
        // Linerange. We expand line ranges to actual lines at this point.
        var splitPos = k.indexOf("-");
        int start = int.parse(k.substring(0, splitPos));
        int end = int.parse(k.substring(splitPos + 1, k.length));
        for (var j = start; j <= end; j++) {
          addToMap(source, j, hits[i+1]);
        }
      }
    }
  });
  return hitMap;
}

/// Merges [newMap] into [result].
mergeHitmaps(Map newMap, Map result) {
  newMap.forEach((String file, Map v) {
    if (result.containsKey(file)) {
      v.forEach((int line, int cnt) {
        if (result[file][line] == null) {
          result[file][line] = cnt;
        } else {
          result[file][line] += cnt;
        }
      }); 
    } else {
      result[file] = v;
    }
  });
}

/// Given an absolute path absPath, this function returns a [List] of files
/// are contained by it if it is a directory, or a [List] containing the file if
/// it is a file.
List filesToProcess(String absPath) {
  if (FileSystemEntity.isDirectorySync(absPath)) {
    Directory d = new Directory(absPath);
    List files = [];
    d.listSync(recursive: true).forEach((FileSystemEntity entity) {
      if (entity is File) {
        files.add(entity as File);
      }
    });
    return files;
  } else if (FileSystemEntity.isFileSync(absPath)) {
    return [ new File(absPath) ];
  } 
}

worker() {
  final start = new DateTime.now().millisecondsSinceEpoch;
  String me = currentMirrorSystem().isolate.debugName;

  port.receive((Message message, reply) {
    if (message.type == Message.SHUTDOWN) {
      port.close();
    }

    if (message.type == Message.WORK) {
      var env = message.payload[0];
      List files = message.payload[1];
      Resolver resolver = new Resolver(env);
      var workerHitmap = {};
      files.forEach((File fileEntry) {
        // Read file sync, as it only contains 1 object.
        String contents = fileEntry.readAsStringSync();
        if (contents.length > 0) {
          mergeHitmaps(createHitmap(contents, resolver), workerHitmap);
        }
      }); 
      if (env["verbose"]) {
        final end = new DateTime.now().millisecondsSinceEpoch;
        print("worker[${me}]: Finished processing files. "
              "Took ${end - start} ms.");
      }
      reply.send(new Message(Message.RESULT, [workerHitmap, resolver.failed]));
    }

  });
}

class Message {
  static const int SHUTDOWN = 1;
  static const int RESULT = 2;
  static const int WORK = 3;

  final int type;
  final payload;

  Message(this.type, this.payload);
}

final env = new Environment();

main() {
  parseArgs();

  List files = filesToProcess(env.input);
  int filesPerWorker = files.length ~/ env.workers;
  List workerPorts = [];
  int doneCnt = 0;

  List failedResolves = [];
  List failedLoads = [];
  Map globalHitmap = {};
  int start = new DateTime.now().millisecondsSinceEpoch;

  if (env.verbose) {
    print("Environment:");
    print("  # files: ${files.length}");
    print("  # workers: ${env.workers}");
    print("  sdk-root: ${env.sdkRoot}");
    print("  package-root: ${env.pkgRoot}");
  }

  port.receive((Message message, reply) {
    if (message.type == Message.RESULT) {
      mergeHitmaps(message.payload[0], globalHitmap);  
      failedResolves.addAll(message.payload[1]);
      doneCnt++;
    }

    // All workers are done. Process the data.
    if (doneCnt == env.workers) {
      workerPorts.forEach((p) => p.send(new Message(Message.SHUTDOWN, null)));
      if (env.verbose) {
        final end = new DateTime.now().millisecondsSinceEpoch;
        print("Done creating a global hitmap. Took ${end - start} ms.");
      }

      Future out;
      if (env.prettyPrint) {
        out = prettyPrint(globalHitmap, failedLoads);
      }
      if (env.lcov) {
        out = lcov(globalHitmap);
      }

      out.then((_) {
        env.output.close().then((_) {
          if (env.verbose) {
            final end = new DateTime.now().millisecondsSinceEpoch;
            print("Done flushing output. Took ${end - start} ms.");
          }
        });
        port.close();

        if (env.verbose) {
          if (failedResolves.length > 0) {
            print("Failed to resolve:");
            failedResolves.toSet().forEach((e) {
              print("  ${e}");
            });
          }
          if (failedLoads.length > 0) {
            print("Failed to load:");
            failedLoads.toSet().forEach((e) {
              print("  ${e}");
            });
          }
        }

      });
    }
  });

  Map sharedEnv = {
    "sdkRoot": env.sdkRoot,
    "pkgRoot": env.pkgRoot,
    "verbose": env.verbose,
  };

  // Create workers.
  for (var i = 1; i < env.workers; i++) {
    var p = spawnFunction(worker);
    workerPorts.add(p);
    var start = files.length - filesPerWorker;
    var end = files.length;
    var workerFiles = files.getRange(start, end).toList();
    files.removeRange(start, end);
    p.send(new Message(Message.WORK, [sharedEnv, workerFiles]), port);
  }
  // Let the last worker deal with the rest of the files (which should be only
  // off by at max (#workers - 1).
  var p = spawnFunction(worker);
  workerPorts.add(p);
  p.send(new Message(Message.WORK, [sharedEnv, files]), port);

  return 0;
}

/// Checks the validity of the provided arguments. Does not initialize actual
/// processing.
parseArgs() {
  var parser = new ArgParser();

  parser.addOption("sdk-root", abbr: "s",
                   help: "path to the SDK root");
  parser.addOption("package-root", abbr: "p",
                   help: "path to the package root",
                   defaultsTo: ".");
  parser.addOption("in", abbr: "i",
                   help: "input(s): may be file or directory",
                   defaultsTo: "stdin");
  parser.addOption("out", abbr: "o",
                   help: "output: may be file or stdout",
                   defaultsTo: "stdout");
  parser.addOption("workers", abbr: "j",
                   help: "number of workers",
                   defaultsTo: "1");
  parser.addFlag("pretty-print", abbr: "r",
                 help: "convert coverage data to pretty print format",
                 negatable: false);
  parser.addFlag("lcov", abbr :"l",
                 help: "convert coverage data to lcov format",
                 negatable: false);
  parser.addFlag("verbose", abbr :"v",
                 help: "verbose output",
                 negatable: false);
  parser.addFlag("help", abbr: "h",
                 help: "show this help",
                 negatable: false);

  var args = parser.parse(new Options().arguments);

  if (args["help"]) {
    print("Usage: coverage [OPTION...]\n");
    print(parser.getUsage());
    exit(0);
  }

  if (args["sdk-root"] == null) {
    if (Platform.environment.containsKey("SDK_ROOT")) {
      env.sdkRoot =
        join(absolute(normalize(Platform.environment["SDK_ROOT"])), "lib");
    } else {
      throw "No SDK root found, please specify one using --sdk-root.";
    }
  } else {
    env.sdkRoot = join(absolute(normalize(args["sdk-root"])), "lib");
  }
  if (!FileSystemEntity.isDirectorySync(env.sdkRoot)) {
    throw "Provided SDK root ${args["sdk-root"]} is not a valid SDK "
          "top-level directory";
  }

  if (args["package-root"] == null) {
    env.pkgRoot = absolute(normalize("./packages"));
  } else {
    env.pkgRoot = absolute(normalize(args["package-root"]));
    if (!FileSystemEntity.isDirectorySync(env.pkgRoot)) {
      throw "Provided package root ${args["package-root"]} is not directory.";
    }
  }

  if (args["in"] == "stdin") {
    env.input = "stdin";
  } else {
    env.input = absolute(normalize(args["in"]));
    if (!FileSystemEntity.isDirectorySync(env.input) &&
        !FileSystemEntity.isFileSync(env.input)) {
      throw "Provided input ${args["in"]} is neither a directory, nor a file.";
    }
  }

  if (args["out"] == "stdout") {
    env.output = stdout;
  } else {
    env.output = absolute(normalize(args["out"]));
    env.output = new File(env.output).openWrite();
  }

  if (args["pretty-print"] &&
      args["lcov"]) {
    throw "Choose either pretty-print or lcov output";
  }

  env.prettyPrint = args["pretty-print"];
  env.lcov = args["lcov"];
  env.verbose = args["verbose"];
  env.workers = int.parse("${args["workers"]}");
}
