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

part of dart.io;

abstract class _IOResourceInfo {
  final String type;
  final int id;
  String get name;
  static int _count = 0;

  static final Stopwatch _sw = new Stopwatch()..start();
  static final _startTime = new DateTime.now().millisecondsSinceEpoch;

  static double get timestamp => _startTime + _sw.elapsedMicroseconds / 1000;

  _IOResourceInfo(this.type) : id = _IOResourceInfo.getNextID();

  /// Get the full set of values for a specific implementation. This is normally
  /// looked up based on an id from a referenceValueMap.
  Map<String, dynamic> get fullValueMap;

  /// The reference map, used to return a list of values, e.g., getting
  /// all open sockets. The structure of this is shared among all subclasses.
  Map<String, dynamic> get referenceValueMap => {
        // The type for a reference object is prefixed with @ in observatory.
        'type': '@$type',
        'id': id,
        'name': name,
      };

  static int getNextID() => _count++;
}

abstract class _ReadWriteResourceInfo extends _IOResourceInfo {
  int totalRead;
  int totalWritten;
  int readCount;
  int writeCount;
  double lastRead;
  double lastWrite;

  // Not all call sites use this. In some cases, e.g., a socket, a read does
  // not always mean that we actually read some bytes (we may do a read to see
  // if there are some bytes available).
  void addRead(int bytes) {
    totalRead += bytes;
    readCount++;
    lastRead = _IOResourceInfo.timestamp;
  }

  // In cases where we read but did not necessarily get any bytes, use this to
  // update the readCount and timestamp. Manually update totalRead if any bytes
  // where actually read.
  void didRead() {
    addRead(0);
  }

  void addWrite(int bytes) {
    totalWritten += bytes;
    writeCount++;
    lastWrite = _IOResourceInfo.timestamp;
  }

  _ReadWriteResourceInfo(String type)
      : totalRead = 0,
        totalWritten = 0,
        readCount = 0,
        writeCount = 0,
        lastRead = 0.0,
        lastWrite = 0.0,
        super(type);

  Map<String, dynamic> get fullValueMap => {
        'type': type,
        'id': id,
        'name': name,
        'totalRead': totalRead,
        'totalWritten': totalWritten,
        'readCount': readCount,
        'writeCount': writeCount,
        'lastRead': lastRead,
        'lastWrite': lastWrite
      };
}

class _FileResourceInfo extends _ReadWriteResourceInfo {
  static const String _type = '_file';

  final file;

  static Map<int, _FileResourceInfo> openFiles =
      new Map<int, _FileResourceInfo>();

  _FileResourceInfo(this.file) : super(_type) {
    FileOpened(this);
  }

  static FileOpened(_FileResourceInfo info) {
    assert(!openFiles.containsKey(info.id));
    openFiles[info.id] = info;
  }

  static FileClosed(_FileResourceInfo info) {
    assert(openFiles.containsKey(info.id));
    openFiles.remove(info.id);
  }

  static Iterable<Map<String, dynamic>> getOpenFilesList() {
    return new List.from(openFiles.values.map((e) => e.referenceValueMap));
  }

  static Future<ServiceExtensionResponse> getOpenFiles(function, params) {
    assert(function == 'ext.dart.io.getOpenFiles');
    var data = {'type': '_openfiles', 'data': getOpenFilesList()};
    var jsonValue = json.encode(data);
    return new Future.value(new ServiceExtensionResponse.result(jsonValue));
  }

  Map<String, dynamic> getFileInfoMap() {
    return fullValueMap;
  }

  static Future<ServiceExtensionResponse> getFileInfoMapByID(function, params) {
    assert(params.containsKey('id'));
    var id = int.parse(params['id']);
    var result =
        openFiles.containsKey(id) ? openFiles[id].getFileInfoMap() : {};
    var jsonValue = json.encode(result);
    return new Future.value(new ServiceExtensionResponse.result(jsonValue));
  }

  String get name {
    return '${file.path}';
  }
}

class _ProcessResourceInfo extends _IOResourceInfo {
  static const String _type = '_process';
  final process;
  final double startedAt;

  static Map<int, _ProcessResourceInfo> startedProcesses =
      new Map<int, _ProcessResourceInfo>();

  _ProcessResourceInfo(this.process)
      : startedAt = _IOResourceInfo.timestamp,
        super(_type) {
    ProcessStarted(this);
  }

  String get name => process._path;

  void stopped() {
    ProcessStopped(this);
  }

  Map<String, dynamic> get fullValueMap => {
        'type': type,
        'id': id,
        'name': name,
        'pid': process.pid,
        'startedAt': startedAt,
        'arguments': process._arguments,
        'workingDirectory':
            process._workingDirectory == null ? '.' : process._workingDirectory,
      };

  static ProcessStarted(_ProcessResourceInfo info) {
    assert(!startedProcesses.containsKey(info.id));
    startedProcesses[info.id] = info;
  }

  static ProcessStopped(_ProcessResourceInfo info) {
    assert(startedProcesses.containsKey(info.id));
    startedProcesses.remove(info.id);
  }

  static Iterable<Map<String, dynamic>> getStartedProcessesList() =>
      new List.from(startedProcesses.values.map((e) => e.referenceValueMap));

  static Future<ServiceExtensionResponse> getStartedProcesses(
      String function, Map<String, String> params) {
    assert(function == 'ext.dart.io.getProcesses');
    var data = {'type': '_startedprocesses', 'data': getStartedProcessesList()};
    var jsonValue = json.encode(data);
    return new Future.value(new ServiceExtensionResponse.result(jsonValue));
  }

  static Future<ServiceExtensionResponse> getProcessInfoMapById(
      String function, Map<String, String> params) {
    var id = int.parse(params['id']);
    var result = startedProcesses.containsKey(id)
        ? startedProcesses[id].fullValueMap
        : {};
    var jsonValue = json.encode(result);
    return new Future.value(new ServiceExtensionResponse.result(jsonValue));
  }
}

class _SocketResourceInfo extends _ReadWriteResourceInfo {
  static const String _tcpString = 'TCP';
  static const String _udpString = 'UDP';
  static const String _type = '_socket';

  final /*_NativeSocket|*/ socket;

  static Map<int, _SocketResourceInfo> openSockets =
      new Map<int, _SocketResourceInfo>();

  _SocketResourceInfo(this.socket) : super(_type) {
    SocketOpened(this);
  }

  String get name {
    if (socket.isListening) {
      return 'listening:${socket.address.host}:${socket.port}';
    }
    var remote = '';
    try {
      var remoteHost = socket.remoteAddress.host;
      var remotePort = socket.remotePort;
      remote = ' -> $remoteHost:$remotePort';
    } catch (e) {} // ignored if we can't get the information
    return '${socket.address.host}:${socket.port}$remote';
  }

  static Iterable<Map<String, dynamic>> getOpenSocketsList() {
    return new List.from(openSockets.values.map((e) => e.referenceValueMap));
  }

  Map<String, dynamic> getSocketInfoMap() {
    var result = fullValueMap;
    result['socketType'] = socket.isTcp ? _tcpString : _udpString;
    result['listening'] = socket.isListening;
    result['host'] = socket.address.host;
    result['port'] = socket.port;
    if (!socket.isListening) {
      try {
        result['remoteHost'] = socket.remoteAddress.host;
        result['remotePort'] = socket.remotePort;
      } catch (e) {
        // UDP.
        result['remotePort'] = 'NA';
        result['remoteHost'] = 'NA';
      }
    } else {
      result['remotePort'] = 'NA';
      result['remoteHost'] = 'NA';
    }
    result['addressType'] = socket.address.type.name;
    return result;
  }

  static Future<ServiceExtensionResponse> getSocketInfoMapByID(
      String function, Map<String, String> params) {
    assert(params.containsKey('id'));
    var id = int.parse(params['id']);
    var result =
        openSockets.containsKey(id) ? openSockets[id].getSocketInfoMap() : {};
    var jsonValue = json.encode(result);
    return new Future.value(new ServiceExtensionResponse.result(jsonValue));
  }

  static Future<ServiceExtensionResponse> getOpenSockets(function, params) {
    assert(function == 'ext.dart.io.getOpenSockets');
    var data = {'type': '_opensockets', 'data': getOpenSocketsList()};
    var jsonValue = json.encode(data);
    return new Future.value(new ServiceExtensionResponse.result(jsonValue));
  }

  static SocketOpened(_SocketResourceInfo info) {
    assert(!openSockets.containsKey(info.id));
    openSockets[info.id] = info;
  }

  static SocketClosed(_SocketResourceInfo info) {
    assert(openSockets.containsKey(info.id));
    openSockets.remove(info.id);
  }
}
