// Copyright 2016 The Vanadium Authors. 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:io';
import 'dart:convert' show JSON;
import 'dart:collection';

import 'package:flutter_driver/flutter_driver.dart';

import 'common.dart';

/// Singleton pattern is used to load config data only once.
class Meta {
  dynamic _config;

  static Meta instance;

  factory Meta() {
    if (instance == null) {
      // Read the temp spec file to find the device nickname -> observatory port
      // mapping.
      Directory systemTempDir = Directory.systemTemp;
      File tempFile = new File('${systemTempDir.path}/$defaultTempSpecsName');
      // if temp spec file is not found, report error and exit.
      if(!tempFile.existsSync()) {
        stderr.writeln('mdtest temporary specs file not found.');
        exit(1);
      }
      // Decode specs assuming no exception, because the temp file is
      // generated by mdtest.
      dynamic config = JSON.decode(tempFile.readAsStringSync());
      instance = new Meta._internal(config);
    }
    return instance;
  }

  dynamic get config => instance._config;

  Meta._internal(this._config);
}

class DriverMap extends UnmodifiableMapBase<String, Future<FlutterDriver>> {

  Meta _meta;
  Map<String, FlutterDriver> _map;

  DriverMap() {
    _meta = new Meta();
    _map = <String, FlutterDriver>{};
  }

  /// Lazy initializing flutter driver given the nickname.  If the nickname
  /// does not exist in the test spec, report error and return null.  Otherwise,
  /// if the flutter driver associated with the nickname is not initialized,
  /// initialize the driver.  If the flutter driver is initialized, return it.
  @override
  Future<FlutterDriver> operator [](String nickname) async {
    dynamic config = _meta.config;
    if (config.containsKey(nickname)) {
      if (!_map.containsKey(nickname)) {
        String observatoryUrl = config[nickname]['observatory-url'];
        // Delegate to flutter driver connect method.
        FlutterDriver driver
          = await FlutterDriver.connect(dartVmServiceUrl: '$observatoryUrl');
        _map[nickname] = driver;
        return driver;
      }
      return _map[nickname];
    }
    stderr.writeln('Device nickname $nickname not found.');
    return null;
  }

  @override
  Iterable<String> get keys => _meta.config.keys;

  /// Close all connected drivers.
  void closeAll() {
    keys.forEach((String nickname) async {
      FlutterDriver driver = await this[nickname];
      if (driver != null) {
        await driver.close();
      }
    });
  }
}
