// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// ignore_for_file: avoid_print, avoid_dynamic_calls

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

import 'package:args/args.dart';
import 'package:imitation_game/readme_template.dart';
import 'package:mustache_template/mustache.dart';

// ignore_for_file: avoid_as

const int _port = 4040;

Future<String?> _findIpAddress() async {
  String? result;
  final List<NetworkInterface> interfaces = await NetworkInterface.list();
  for (final NetworkInterface interface in interfaces) {
    for (final InternetAddress address in interface.addresses) {
      if (address.type == InternetAddressType.IPv4) {
        // TODO(gaaclarke): Implment having multiple addresses.
        assert(result == null);
        result = address.address;
      }
    }
  }
  return result;
}

Future<String> _getFlutterVersion() async {
  String result = '';
  final Process flutterVersion =
      await Process.start('flutter', <String>['--version']);
  flutterVersion.stdout.transform(utf8.decoder).listen((String event) {
    result += event;
  });
  await flutterVersion.exitCode;
  return result.trim();
}

typedef FileFilter = bool Function(FileSystemEntity);
Future<List<FileSystemEntity>> findFiles(Directory dir, {FileFilter? where}) {
  final List<FileSystemEntity> files = <FileSystemEntity>[];
  final Completer<List<FileSystemEntity>> completer =
      Completer<List<FileSystemEntity>>();
  final Stream<FileSystemEntity> lister = dir.list(recursive: true);
  lister.listen((FileSystemEntity file) {
    if (where == null || where(file)) {
      files.add(file);
    }
  }, onDone: () => completer.complete(files));
  return completer.future;
}

Future<String> _makeMarkdownOutput(Map<String, dynamic> results) async {
  // TODO(gaaclarke): Add the Flutter version.
  final Template template = Template(readmeTemplate, name: 'README.md');
  final Map<String, dynamic> values = Map<String, dynamic>.from(results);
  values['date'] = DateTime.now().toUtc();
  values['flutterVersion'] = await _getFlutterVersion();
  final String output = template.renderString(values);
  return output;
}

/// This merges [newResults] into [oldResults] such the union of the keys will
/// have their values from [newResults] and the symmetric difference will have the
/// value from their respective sets.
Map<String, dynamic> _integrate(
    {required Map<String, dynamic> oldResults,
    required Map<String, dynamic> newResults}) {
  final Map<String, dynamic> result = Map<String, dynamic>.from(oldResults);
  newResults.forEach((String test, dynamic testValue) {
    final Map<String, dynamic> testMap = testValue as Map<String, dynamic>;
    testMap.forEach((String platform, dynamic platformValue) {
      final Map<String, dynamic> platformMap =
          platformValue as Map<String, dynamic>;
      platformMap.forEach((String measurement, dynamic measurementValue) {
        if (!result.containsKey(test)) {
          result[test] = <String, dynamic>{};
        }
        if (!result[test].containsKey(platform)) {
          result[test][platform] = <String, dynamic>{};
        }
        result[test][platform][measurement] = measurementValue;
      });
    });
  });
  return result;
}

class _Script {
  _Script({required this.path});
  String path;
}

class _ScriptRunner {
  _ScriptRunner(this._scriptPaths);

  final List<String> _scriptPaths;
  Process? _currentProcess;
  late StreamSubscription<String> _stdoutSubscription;
  late StreamSubscription<String> _stderrSubscription;

  Future<_Script?> runNext() async {
    if (_currentProcess != null) {
      _stdoutSubscription.cancel();
      _stderrSubscription.cancel();
      _currentProcess!.kill();
      _currentProcess = null;
    }

    if (_scriptPaths.isEmpty) {
      return null;
    } else {
      final String path = _scriptPaths.last;
      print('running: $path');
      _scriptPaths.removeLast();
      _currentProcess = await Process.start('sh', <String>[path]);
      // TODO(gaaclarke): Implement a timeout.
      _stdoutSubscription =
          _currentProcess!.stdout.transform(utf8.decoder).listen((String data) {
        print(data);
      });
      _stderrSubscription =
          _currentProcess!.stderr.transform(utf8.decoder).listen((String data) {
        print(data);
      });
      return _Script(path: path);
    }
  }
}

/// Recursively converts a map of maps to a map of lists of maps.
///
/// For example:
/// _map2List({'a': {'b': 123}}, ['foo', 'bar']) ->
/// {
///   'foo':[
///     {
///       'name': 'a',
///       'bar': [{'name': 'b', 'value': 123}]
///     }
///   ]
/// }
Map<String, dynamic> _map2List(Map<String, dynamic> map, List<String> names) {
  final List<Map<String, dynamic>> returnList = <Map<String, dynamic>>[];
  final List<String> tail = names.sublist(1);
  map.forEach((String key, dynamic value) {
    final Map<String, dynamic> testResult = <String, dynamic>{'name': key};
    if (tail.isEmpty) {
      testResult['value'] = value;
    } else {
      testResult[tail.first] = _map2List(value, tail)[tail.first];
    }
    returnList.add(testResult);
  });
  return <String, dynamic>{names.first: returnList};
}

class _ImitationGame {
  final Map<String, dynamic> results = <String, dynamic>{};
  late _ScriptRunner _scriptRunner;
  _Script? _currentScript;

  Future<bool> start(List<String> iosScripts) {
    _scriptRunner = _ScriptRunner(iosScripts);
    return _runNext();
  }

  Future<bool> handleResult(Map<String, dynamic> data) {
    final String test = data['test'];
    final String? platform = data['platform'];
    results.putIfAbsent(test, () => <String, dynamic>{});
    results[test].putIfAbsent(platform, () => <String, dynamic>{});
    data['results'].forEach((String k, dynamic v) {
      results[test][platform][k] = v as double;
    });
    return _runNext();
  }

  Future<bool> handleTimeout() {
    return _runNext();
  }

  Future<bool> _runNext() async {
    _currentScript = await _scriptRunner.runNext();
    return _currentScript != null;
  }
}

enum _TargetPlatform { ANDROID, IOS }

Future<void> main(List<String> args) async {
  final ArgParser parser = ArgParser();
  parser.addOption('platform',
      allowed: <String>['android', 'ios'], defaultsTo: 'android');
  final ArgResults parserResults = parser.parse(args);
  final _TargetPlatform targetPlatform = parserResults['platform'] == 'android'
      ? _TargetPlatform.ANDROID
      : _TargetPlatform.IOS;

  final HttpServer server = await HttpServer.bind(
    InternetAddress.anyIPv4,
    _port,
  );
  final String? ipaddress = await _findIpAddress();
  print('Listening on $ipaddress:${server.port}');

  for (final FileSystemEntity entity in await findFiles(Directory.current,
      where: (FileSystemEntity f) => f.path.endsWith('ip.txt'))) {
    final File file = File(entity.path);
    file.writeAsStringSync('$ipaddress:${server.port}');
  }

  final String scriptName = (targetPlatform == _TargetPlatform.ANDROID)
      ? 'run_android.sh'
      : () {
          assert(targetPlatform == _TargetPlatform.IOS);
          return 'run_ios.sh';
        }();
  final List<String> scripts = (await findFiles(Directory.current,
          where: (FileSystemEntity f) => f.path.endsWith(scriptName)))
      .map((FileSystemEntity e) => e.path)
      .toList();

  if (scripts.isEmpty) {
    return;
  }

  final _ImitationGame game = _ImitationGame();
  bool keepRunning = await game.start(scripts);

  while (keepRunning) {
    try {
      final Stream<HttpRequest> timeoutServer = server.timeout(
          const Duration(minutes: 5), onTimeout: (EventSink<HttpRequest> sink) {
        print('TIMEOUT!');
        throw TimeoutException('timeout');
      });
      await for (final HttpRequest request in timeoutServer) {
        print('got request: ${request.method}');
        if (request.method == 'POST') {
          final String content = await utf8.decoder.bind(request).join();
          final Map<String, dynamic> data =
              jsonDecode(content) as Map<String, dynamic>;
          print('$data');
          keepRunning = await game.handleResult(data);
          if (!keepRunning) {
            break;
          }
        } else {
          request.response.write('use post');
        }
        await request.response.close();
      }
    } on TimeoutException catch (_) {
      keepRunning = await game.handleTimeout();
    }
  }

  // TODO(gaaclarke): Add a log of what Flutter version generated the numbers.
  const String lastResultsFilename = 'last_results.json';
  const JsonDecoder decoder = JsonDecoder();
  final Map<String, dynamic> lastResults =
      decoder.convert(File(lastResultsFilename).readAsStringSync())
          as Map<String, dynamic>;

  // TODO(aaclarke): Calculate the generation time for each measurement since we
  // can't generate everything in one pass (because you are running iOS or Android).
  final Map<String, dynamic> totalResults =
      _integrate(newResults: game.results, oldResults: lastResults);

  const JsonEncoder encoder = JsonEncoder.withIndent('  ');
  final String jsonResults = encoder.convert(totalResults);
  File(lastResultsFilename).writeAsStringSync(jsonResults);

  final Map<String, dynamic> markdownValues =
      _map2List(totalResults, <String>['tests', 'platforms', 'measurements']);
  File('README.md')
      .writeAsStringSync(await _makeMarkdownOutput(markdownValues));
  await server.close(force: true);
}
