// Copyright (c) 2012, 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.

library builtin;
import 'dart:io';
import 'dart:async';
// import 'root_library'; happens here from C Code

// The root library (aka the script) is imported into this library. The
// standalone embedder uses this to lookup the main entrypoint in the
// root library's namespace.
Function _getMainClosure() => main;


// Corelib 'print' implementation.
void _print(arg) {
  _Logger._printString(arg.toString());
}


class _Logger {
  static void _printString(String s) native "Logger_PrintString";
}


_getPrintClosure() => _print;


void _logResolution(String msg) {
  final enabled = false;
  if (enabled) {
    _Logger._printString(msg);
  }
}


// Corelib 'Uri.base' implementation.
Uri _uriBase() {
  return new Uri.file(Directory.current.path + "/");
}

_getUriBaseClosure() => _uriBase;


var _httpRequestResponseCode = 0;
var _httpRequestStatusString;
var _httpRequestResponse;

_getHttpRequestResponseCode() => _httpRequestResponseCode;
_getHttpRequestStatusString() => _httpRequestStatusString;
_getHttpRequestResponse() => _httpRequestResponse;

void _requestCompleted(List<int> data, HttpClientResponse response) {
  _httpRequestResponseCode = response.statusCode;
  _httpRequestStatusString = '${response.statusCode} ${response.reasonPhrase}';
  _httpRequestResponse = null;
  if (response.statusCode != 200 ||
      (response.headers.contentType != null &&
       response.headers.contentType.mimeType == 'application/json')) {
    return;
  }
  _httpRequestResponse = data;
}


void _requestFailed(error) {
  _httpRequestResponseCode = 0;
  _httpRequestStatusString = error.toString();
  _httpRequestResponse = null;
}


void _makeHttpRequest(String uri) {
  var _client = new HttpClient();
  _httpRequestResponseCode = 0;
  _httpRequestStatusString = null;
  _httpRequestResponse = null;
  try {
    Uri requestUri = Uri.parse(uri);
    _client.getUrl(requestUri)
        .then((HttpClientRequest request) => request.close())
        .then((HttpClientResponse response) {
          return response
              .fold(new BytesBuilder(), (b, d) => b..add(d))
              .then((builder) {
                _requestCompleted(builder.takeBytes(), response);
                // This client is only used for a single request. Force closing
                // it now otherwise we wait around until it times out.
                _client.close(force:true);
              });
        }).catchError((error) {
          _requestFailed(error);
        });
  } catch (error) {
    _requestFailed(error);
  }
  // TODO(floitsch): remove this line. It's just here to push an event on the
  // event loop so that we invoke the scheduled microtasks. Also remove the
  // import of dart:async when this line is not needed anymore.
  Timer.run(() {});
}


// Are we running on Windows?
var _isWindows = false;
var _workingWindowsDrivePrefix;
// The current working directory
var _workingDirectoryUri;
// The URI that the entry point script was loaded from. Remembered so that
// package imports can be resolved relative to it.
var _entryPointScript;
// The directory to look in to resolve "package:" scheme URIs.
var _packageRoot;


void _setWindows() {
  _isWindows = true;
}


_sanitizeWindowsPath(path) {
  // For Windows we need to massage the paths a bit according to
  // http://blogs.msdn.com/b/ie/archive/2006/12/06/file-uris-in-windows.aspx
  //
  // Convert
  // C:\one\two\three
  // to
  // /C:/one/two/three

  if (_isWindows == false) {
    // Do nothing when not running Windows.
    return path;
  }

  var fixedPath = "${path.replaceAll('\\', '/')}";

  if ((path.length > 2) && (path[1] == ':')) {
    // Path begins with a drive letter.
    return '/$fixedPath';
  }

  return fixedPath;
}


_enforceTrailingSlash(uri) {
  // Ensure we have a trailing slash character.
  if (!uri.endsWith('/')) {
    return '$uri/';
  }
  return uri;
}


_extractDriveLetterPrefix(cwd) {
  if (!_isWindows) {
    return null;
  }
  if (cwd.length > 1 && cwd[1] == ':') {
    return '/${cwd[0]}:';
  }
  return null;
}


void _setWorkingDirectory(cwd) {
  _workingWindowsDrivePrefix = _extractDriveLetterPrefix(cwd);
  cwd = _sanitizeWindowsPath(cwd);
  cwd = _enforceTrailingSlash(cwd);
  _workingDirectoryUri = new Uri(scheme: 'file', path: cwd);
  _logResolution('# Working Directory: $cwd');
}


_setPackageRoot(String packageRoot) {
  packageRoot = _enforceTrailingSlash(packageRoot);
  if (packageRoot.startsWith('file:') ||
      packageRoot.startsWith('http:') ||
      packageRoot.startsWith('https:')) {
    _packageRoot = _workingDirectoryUri.resolve(packageRoot);
  } else {
    _packageRoot = _workingDirectoryUri.resolveUri(new Uri.file(packageRoot));
  }
  _logResolution('# Package root: $packageRoot -> $_packageRoot');
}


String _resolveScriptUri(String scriptName) {
  if (_workingDirectoryUri == null) {
    throw 'No current working directory set.';
  }
  scriptName = _sanitizeWindowsPath(scriptName);

  var scriptUri = Uri.parse(scriptName);
  if (scriptUri.scheme != '') {
    // Script has a scheme, assume that it is fully formed.
    _entryPointScript = scriptUri;
  } else {
    // Script does not have a scheme, assume that it is a path,
    // resolve it against the working directory.
    _entryPointScript = _workingDirectoryUri.resolve(scriptName);
  }
  _logResolution('# Resolved entry point to: $_entryPointScript');
  return _entryPointScript.toString();
}


String _resolveUri(String base, String userString) {
  var baseUri = Uri.parse(base);
  _logResolution('# Resolving: $userString from $base');

  var uri = Uri.parse(userString);
  var resolved;
  if ('dart-ext' == uri.scheme) {
    // Relative URIs with scheme dart-ext should be resolved as if with no
    // scheme.
    resolved = baseUri.resolve(uri.path);
    if (resolved.scheme == 'package') {
      // If we are resolving relative to a package URI we go directly to the
      // file path and keep the dart-ext scheme. Otherwise, we will lose the
      // package URI path part.
      var path = _filePathFromPackageUri(resolved);
      if (path.startsWith('http:')) {
        throw "Native extensions not supported in "
            "packages loaded over http: %path";
      }
      resolved = new Uri.file(path);
    }
    resolved = new Uri(scheme: 'dart-ext', path: resolved.path);
  } else {
    resolved = baseUri.resolve(userString);
  }
  _logResolution('# Resolved to: $resolved');
  return resolved.toString();
}


// Returns either a file path or a URI starting with http:, as a String.
String _filePathFromUri(String userUri) {
  var uri = Uri.parse(userUri);
  _logResolution('# Getting file path from: $uri');

  var path;
  switch (uri.scheme) {
    case '':
    case 'file':
      return uri.toFilePath();
      break;
    case 'dart-ext':
      // Relative file URIs don't start with file:///.
      var scheme = (uri.path.startsWith('/') ? 'file' : '');
      return new Uri(scheme: scheme,
                     host: uri.host,
                     path: uri.path).toFilePath();
      break;
    case 'package':
      return _filePathFromPackageUri(uri);
      break;
    case 'http':
      return uri.toString();
    default:
      // Only handling file, dart-ext, http, and package URIs
      // in standalone binary.
      _logResolution('# Unknown scheme (${uri.scheme}) in $uri.');
      throw 'Not a known scheme: $uri';
  }
}


String _filePathFromPackageUri(Uri uri) {
  if (!uri.host.isEmpty) {
    var path = (uri.path != '') ? '${uri.host}${uri.path}' : uri.host;
    var right = 'package:$path';
    var wrong = 'package://$path';

    throw "URIs using the 'package:' scheme should look like "
          "'$right', not '$wrong'.";
  }

  var packageRoot = _packageRoot == null ?
                    _entryPointScript.resolve('packages/') :
                    _packageRoot;
  return _filePathFromUri(packageRoot.resolve(uri.path).toString());
}
