// 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.

library utils;

import 'dart:io';
import 'dart:convert';

import 'path.dart';

// This is the maximum time we expect stdout/stderr of subprocesses to deliver
// data after we've got the exitCode.
const Duration MAX_STDIO_DELAY = const Duration(seconds: 30);

String MAX_STDIO_DELAY_PASSED_MESSAGE =
"""Not waiting for stdout/stderr from subprocess anymore 
($MAX_STDIO_DELAY passed). Please note that this could be an indicator 
that there is a hanging process which we were unable to kill.""";

class DebugLogger {
  static IOSink _sink;

  /**
   * If [path] was null, the DebugLogger will write messages to stdout.
   */
  static init(Path path, {append: false}) {
    if (path != null) {
      var mode = append ? FileMode.APPEND : FileMode.WRITE;
      _sink = new File(path.toNativePath()).openWrite(mode: mode);
    }
  }

  static void close() {
    if (_sink != null) {
      _sink.close();
      _sink = null;
    }
  }

  static String _formatErrorMessage(String msg, error) {
    if (error == null) return msg;
    msg += ": $error";
    // TODO(floitsch): once the dart-executable that is bundled
    // with the Dart sources is updated, pass a trace parameter too and do:
    // if (trace != null) msg += "\nStackTrace: $trace";
    return msg;
  }
  static void info(String msg, [error]) {
    msg = _formatErrorMessage(msg, error);
    _print("$_datetime Info: $msg");
  }

  static void warning(String msg, [error]) {
    msg = _formatErrorMessage(msg, error);
    _print("$_datetime Warning: $msg");
  }

  static void error(String msg, [error]) {
    msg = _formatErrorMessage(msg, error);
    _print("$_datetime Error: $msg");
  }

  static void _print(String msg) {
    if (_sink != null) {
      _sink.writeln(msg);
    } else {
      print(msg);
    }
  }

  static String get _datetime => "${new DateTime.now()}";
}

String prettifyJson(Object json, {int startIndentation: 0, int shiftWidth: 6}) {
  int currentIndentation = startIndentation;
  var buffer = new StringBuffer();

  String indentationString() {
    return new List.filled(currentIndentation, ' ').join('');
  }

  addString(String s, {bool indentation: true, bool newLine: true}) {
    if (indentation) {
      buffer.write(indentationString());
    }
    buffer.write(s.replaceAll("\n", "\n${indentationString()}"));
    if (newLine) buffer.write("\n");
  }

  prettifyJsonInternal(
      Object obj, {bool indentation: true, bool newLine: true}) {
    if (obj is List) {
      addString("[", indentation: indentation);
      currentIndentation += shiftWidth;
      for (var item in obj) {

        prettifyJsonInternal(item, indentation: indentation, newLine: false);
        addString(",", indentation: false);
      }
      currentIndentation -= shiftWidth;
      addString("]", indentation: indentation);
    } else if (obj is Map) {
      addString("{", indentation: indentation);
      currentIndentation += shiftWidth;
      for (var key in obj.keys) {
        addString("$key: ", indentation: indentation, newLine: false);
        currentIndentation += shiftWidth;
        prettifyJsonInternal(obj[key], indentation: false);
        currentIndentation -= shiftWidth;
      }
      currentIndentation -= shiftWidth;
      addString("}", indentation: indentation, newLine: newLine);
    } else {
      addString("$obj", indentation: indentation, newLine: newLine);
    }
  }
  prettifyJsonInternal(json);
  return buffer.toString();
}


/**
 * [areByteArraysEqual] compares a range of bytes from [buffer1] with a
 * range of bytes from [buffer2].
 *
 * Returns [true] if the [count] bytes in [buffer1] (starting at
 * [offset1]) match the [count] bytes in [buffer2] (starting at
 * [offset2]).
 * Otherwise [false] is returned.
 */
bool areByteArraysEqual(List<int> buffer1, int offset1,
                        List<int> buffer2, int offset2,
                        int count) {
  if ((offset1 + count) > buffer1.length ||
      (offset2 + count) > buffer2.length) {
    return false;
  }

  for (var i = 0; i < count; i++) {
    if (buffer1[offset1 + i] != buffer2[offset2 + i]) {
      return false;
    }
  }
  return true;
}

/**
 * [findBytes] searches for [pattern] in [data] beginning at [startPos].
 *
 * Returns [true] if [pattern] was found in [data].
 * Otherwise [false] is returned.
 */
int findBytes(List<int> data, List<int> pattern, [int startPos=0]) {
  // TODO(kustermann): Use one of the fast string-matching algorithms!
  for (int i = startPos; i < (data.length - pattern.length); i++) {
    bool found = true;
    for (int j = 0; j < pattern.length; j++) {
      if (data[i + j] != pattern[j]) {
        found = false;
        break;
      }
    }
    if (found) {
      return i;
    }
  }
  return -1;
}

List<int> encodeUtf8(String string) {
  return UTF8.encode(string);
}

// TODO(kustermann,ricow): As soon we have a debug log we should log
// invalid utf8-encoded input to the log.
// Currently invalid bytes will be replaced by a replacement character.
String decodeUtf8(List<int> bytes) {
  return UTF8.decode(bytes, allowMalformed: true);
}

class Locations {
  static String getBrowserLocation(String browserName,
                                   Map globalConfiguration) {
    var location = globalConfiguration[browserName];
    if (location != null && location != '') {
      return location;
    }
    var browserLocations = {
        'firefox': const {
          'windows': 'C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe',
          'linux': 'firefox',
          'macos': '/Applications/Firefox.app/Contents/MacOS/firefox'
        },
        'chrome': const {
          'windows':
            'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe',
          'macos':
            '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
          'linux': 'google-chrome'
        },
        'dartium': const {
          'windows': 'client\\tests\\dartium\\chrome.exe',
          'macos': 'client/tests/dartium/Chromium.app/Contents/MacOS/Chromium',
          'linux': 'client/tests/dartium/chrome'
        },
        'safari': const {
          'macos': '/Applications/Safari.app/Contents/MacOS/Safari'
        },
        'safarimobilesim': const {
          'macos': '/Applications/Xcode.app/Contents/Developer/Platforms/'
                   'iPhoneSimulator.platform/Developer/Applications/'
                   'iPhone Simulator.app/Contents/MacOS/iPhone Simulator'
        },
        'ie9': const {
          'windows': 'C:\\Program Files\\Internet Explorer\\iexplore.exe'
        },
        'ie10': const {
          'windows': 'C:\\Program Files\\Internet Explorer\\iexplore.exe'
        },
        'ie11': const {
          'windows': 'C:\\Program Files\\Internet Explorer\\iexplore.exe'
        }};
    browserLocations['ff'] = browserLocations['firefox'];

    assert(browserLocations[browserName] != null);
    location = browserLocations[browserName][Platform.operatingSystem];
    if (location != null) {
      return location;
    } else {
      throw '$browserName not supported on ${Platform.operatingSystem}';
    }
  }
}

// This function is pretty stupid and only puts quotes around an argument if
// it the argument contains a space.
String escapeCommandLineArgument(String argument) {
  if (argument.contains(' ')) {
    return '"$argument"';
  }
  return argument;
}

class HashCodeBuilder {
  int _value = 0;

  void add(Object object) {
    _value = ((_value * 31) ^ object.hashCode)  & 0x3FFFFFFF;
  }

  void addJson(Object object) {
    if (object == null || object is num || object is String ||
                  object is Uri || object is bool) {
      add(object);
    } else if (object is List) {
      object.forEach(addJson);
    } else if (object is Map) {
      for (var key in object.keys.toList()..sort()) {
        addJson(key);
        addJson(object[key]);
      }
    } else {
      throw new Exception("Can't build hashcode for non json-like object "
          "(${object.runtimeType})");
    }
  }

  int get value => _value;
}

bool deepJsonCompare(Object a, Object b) {
  if (a == null || a is num || a is String || a is Uri) {
    return a == b;
  } else if (a is List) {
    if (b is List) {
      if (a.length != b.length) return false;

      for (int i = 0; i < a.length; i++) {
        if (!deepJsonCompare(a[i], b[i])) return false;
      }
      return true;
    }
    return false;
  } else if (a is Map) {
    if (b is Map) {
      if (a.length != b.length) return false;

      for (var key in a.keys) {
        if (!b.containsKey(key)) return false;
        if (!deepJsonCompare(a[key], b[key])) return false;
      }
      return true;
    }
    return false;
  } else {
    throw new Exception("Can't compare two non json-like objects "
        "(a: ${a.runtimeType}, b: ${b.runtimeType})");
  }
}

class UniqueObject {
  static int _nextId = 1;
  final int _hashCode;

  int get hashCode => _hashCode;
  operator==(other) => other is UniqueObject && _hashCode == other._hashCode;

  UniqueObject() : _hashCode = ++_nextId;
}
