// Copyright 2019 The Fuchsia 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:convert';
import 'dart:io';

import 'package:args/args.dart';
import 'package:test/test.dart';
import 'package:archive/archive.dart';


const String ipv4Env = 'FUCHSIA_IPV4_ADDR';
const String outputEnv = 'FUCHSIA_TEST_OUTDIR';

const int deviceReadyTimeoutSec = 30;

const String defaultActsZipAbsPath = '/etc/connectivity/acts.zip';
const String actsConfigAbsPath = '/etc/connectivity/acts_config.json';
const String actsBinRelPath = 'tools/test/connectivity/acts/framework/acts/bin/act.py';
const String actsFrameworkRelPath = 'tools/test/connectivity/acts/framework';
const String actsOutputPath = '/tmp/logs/tb/latest';
const String actsSummaryFileName = 'test_run_summary.json';

Future<void> waitDeviceReady(final String ip) async {
  for (var i = 0; i < deviceReadyTimeoutSec; i++) {
    final result = Process.runSync('ping', [ip, '-c', '1', '-W', '1']);
    if (result.exitCode == 0) {
      print('Fuchsia device is online @ [$ip].');
      return;
    }
    await Future.delayed(const Duration(seconds: 1));
  }
  throw Exception('Device [$ip] is not ping-able.');
}

String resolveActsPath() {
  final List entities = Directory.current.listSync(recursive: true);
  for (var entity in entities) {
    if(entity.path.endsWith('acts.zip')) {
      return entity.path;
    }
  }
  // Use pre-provisioned 'acts.zip' if it's not found under cur directory
  return defaultActsZipAbsPath;
}

void extractActsZip(final String tmpDirPath) {
  final actsPath = resolveActsPath();
  print('Found "acts.zip" @ [$actsPath].');

  final List<int> bytes = File(actsPath).readAsBytesSync();
  final Archive archive = ZipDecoder().decodeBytes(bytes);

  // Extract the contents of the Zip archive to disk.
  for (ArchiveFile file in archive) {
    String filename = file.name;
    var filepath = '$tmpDirPath/$filename';
    if (file.isFile) {
      List<int> data = file.content;
      File(filepath)
        ..createSync(recursive: true)
        ..writeAsBytesSync(data);
    } else {
      Directory(filepath).create(recursive: true);
    }
  }
}

Future<Process> runActs(final String tmpDirPath, final String tests) {
  final actsBinAbsPath = '$tmpDirPath/$actsBinRelPath';

  final actsArgs = ['-c', actsConfigAbsPath, '-tc']
    ..addAll(tests.split(' '));

  // Set ACTS binary as executable
  Process.runSync('chmod', ['+x', actsBinAbsPath]);

  return Process.start(actsBinAbsPath, actsArgs, environment: {
    'PYTHONPATH': '$tmpDirPath/$actsFrameworkRelPath',
    // Required for some Wifi testcases
    'LANG': 'C.UTF-8',
    'LC_ALL': 'C.UTF-8'
  });
}

void main(final List<String> args) {
  final argResults = (ArgParser()
        ..addOption('tests',
            help: 'Space delimited string of ACTS tests to run.')
        ..addOption('timeout',
            help: 'Timeout in minutes for ACTS test execution.'))
      .parse(args);

  // Fetch env var
  final Map<String, String> envVars = Platform.environment;
  final String ipStr = envVars[ipv4Env];
  final String outputDir = envVars[outputEnv];

  tearDown(() {
    // Copy ACTS output to designated dir for GCS upload
    Process.runSync('/bin/cp', ['-r', actsOutputPath, outputDir]);
  });

  test('ActsSuite', () async {
    // Extract ACTS zip into tmp dir
    final tmpDir = Directory.systemTemp.createTempSync('acts_');
    extractActsZip(tmpDir.path);

    // Wait for device to be online before running tests
    for(var ip in ipStr.split(',')) {
      await waitDeviceReady(ip);
    }

    // Run ACTS tests
    final proc = await runActs(tmpDir.path, argResults['tests']);
    await Future.wait([stdout.addStream(proc.stdout), stderr.addStream(proc.stderr)]);
    expect(await proc.exitCode, equals(0));

    // Assert that ACTS actually ran tests
    final json = File('$actsOutputPath/$actsSummaryFileName').readAsStringSync();
    final data = jsonDecode(json);
    expect(data, contains('Results'));
    expect(data['Summary']['Executed'], isNonZero);
  }, timeout: Timeout(Duration(minutes: int.parse(argResults['timeout']))));
}
