// Copyright (c) 2014, 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:io';
import 'package:http_server/http_server.dart' as http_server;
import 'package:route/server.dart';
import 'package:path/path.dart';
import 'package:http_server/http_server.dart';

/*
 * This program serves a visualization of a JavaScript source map file generated
 * by dart2js or pub.
 *
 * Usage: dart source_map_viewer.dart <path to map file>.
 *
 * The default system browser is started and pointed to the viewer if
 * available.
 */

Directory rootDir = null;
String sourceMapFile;

void main(List<String> args) {
  if (args.length != 1) {
    print('One argument expected; the source map file.');
    exit(-1);
    return;
  }

  File mapFile = new File(args[0]);
  if (!mapFile.existsSync()) {
    print('Map file not found at ${args[0]}');
    exit(-2);
    return;
  }

  sourceMapFile = basename(mapFile.path);
  rootDir = mapFile.parent;
  startServer(rootDir);
}

// Sends the content of the file requested in the path parameter.
void handleFile(HttpRequest request) {
  String path = request.uri.queryParameters["path"];
  if (path == null) {
    request.response.close();
    return;
  }

  path = rootDir.path + '/' + path;
  new File(Uri.parse(path).toFilePath()).openRead()
    .pipe(request.response).catchError((e) {
  print("Error: $e");
    request.response.close();
  });
}

// Sends back the name of the source map file.
void handleSourceMapFile(HttpRequest request) {
  request.response.write(sourceMapFile);
  request.response.close();
}

// Starts an HttpServer rooted in [dir] with two special routes, /file and /map.
//
// /file takes a parameter [path] and serves the content of the specified file
//  in path relative to [dir]
//
// /map serves the name of the map file such that its content can be requested
// with a /file request as above.
void startServer(Directory dir) {
  rootDir = dir;
  // Use port 0 to get an ephemeral port.
  int port = 0;
  HttpServer.bind(InternetAddress.LOOPBACK_IP_V4, port).then((server) {
    port = server.port;
    print("Source mapping server is running on "
           "'http://${server.address.address}:$port/'");
    Router router = new Router(server)
                ..serve('/file').listen(handleFile)
                ..serve('/map').listen(handleSourceMapFile);

    // Set up default handler. This will serve files from our 'build'
    // directory. Disable jail root, as packages are local symlinks.
    VirtualDirectory virDir = new http_server.VirtualDirectory(dir.path)
      ..jailRoot = false
      ..allowDirectoryListing = true;

    virDir.directoryHandler = (dir, request) {
      // Redirect directory requests to index.html files.
      Uri indexUri = new Uri.file(dir.path).resolve('display.html');
      virDir.serveFile(new File(indexUri.toFilePath()), request);
    };

    // Add an error page handler.
    virDir.errorPageHandler = (HttpRequest request) {
      print("Resource not found: ${request.uri.path}");
      request.response.statusCode = HttpStatus.NOT_FOUND;
      request.response.close();
    };

    // Serve everything not routed elsewhere through the virtual directory.
    virDir.serve(router.defaultStream);

    // Start the system' default browser
    startBrowser('http://${server.address.address}:$port/');
  });
}

startBrowser(String url) {
  String command;
  if (Platform.isWindows) {
    command = 'cmd.exe /C start';
  } else if (Platform.isMacOS) {
    command = 'open';
  } else {
    String xdg = '/usr/bin/xdg-open';
    if (new File(xdg).existsSync()) {
      command = xdg;
    } else {
      command = '/usr/bin/google-chrome';
    }
  }

  print('Starting browser: ${command} ${url}');
  Process.run(command, ['$url']).then((ProcessResult result) {
    if (result.exitCode != 0) {
      print(result.stderr);
    }
  });
}