// Copyright 2020 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' show jsonDecode;
import 'dart:core';
import 'dart:io' show Directory, File, Platform, Process, sleep;

import 'package:test/test.dart';

class ZedmonException implements Exception {
  final String message;

  ZedmonException(this.message);

  @override
  String toString() => 'ZedmonException: $message';
}

// Description of the Zedmon device and host-side client.
class ZedmonDescription {
  final double shuntResistance;
  final int timestampIndex;
  final int shuntVoltageIndex;
  final int busVoltageIndex;
  final int powerIndex;

  ZedmonDescription(this.shuntResistance, this.timestampIndex,
      this.shuntVoltageIndex, this.busVoltageIndex, this.powerIndex);
}

// Uses `zedmon describe` to create a ZedmonDescription.
Future<ZedmonDescription> getZedmonDescription(String zedmonPath) async {
  final result = await Process.run(zedmonPath, ['describe']);
  final description = jsonDecode(result.stdout);

  final csvFormat = description['csv_header'].split(',');
  for (var field in [
    'timestamp_micros',
    'shunt_voltage',
    'bus_voltage',
    'power'
  ]) {
    if (!csvFormat.contains(field)) {
      throw ZedmonException('CSV header does not contain field "$field".');
    }
  }

  return ZedmonDescription(
      description['shunt_resistance'],
      csvFormat.indexOf('timestamp_micros'),
      csvFormat.indexOf('shunt_voltage'),
      csvFormat.indexOf('bus_voltage'),
      csvFormat.indexOf('power'));
}

void validateZedmonCsvLine(
    String csvLine, ZedmonDescription desc, double powerTolerance) {
  final parts = csvLine.split(',');
  final shuntVoltage = double.parse(parts[desc.shuntVoltageIndex]);
  final busVoltage = double.parse(parts[desc.busVoltageIndex]);
  final power = double.parse(parts[desc.powerIndex]);

  expect(busVoltage * shuntVoltage / desc.shuntResistance,
      closeTo(power, powerTolerance));
}

// Returns the average power measured by `zedmon record --average` for the
// specified number of seconds.
Future<double> measureAveragePower(String zedmonPath, String tempFilePath,
    ZedmonDescription desc, int seconds) async {
  final result = await Process.run(zedmonPath,
      ['record', '--out', tempFilePath, '--average', '${seconds}s']);
  expect(result.exitCode, equals(0));

  final lines = await File(tempFilePath).readAsLines();
  expect(lines.length, equals(1));

  final parts = lines[0].split(',');
  return double.parse(parts[desc.powerIndex]);
}

// In order to run these tests, the host should be connected to exactly one
// Zedmon device, satisfying:
//  - Hardware version 2.1 (version is printed on the board);
//  - Firmware built from the Zedmon repository's revision cdc9458f45, or
//    equivalent.
//
// The Zedmon must be connected to a test device that:
//  - Consumes a nontrivial amount of power (>1W will certainly suffice);
//  - Consumes nontrial power within 1 second of being connected to power;
//
// Zedmon's relay must be on (its default state) at the beginning of the test.
// The test device will be power-cycled in the course of testing.
Future<void> main() async {
  String zedmonPath;
  ZedmonDescription zedmonDescription;
  Directory tempDir;
  String tempFilePath;

  setUpAll(() async {
    zedmonPath = Platform.script.resolve('runtime_deps/zedmon').toFilePath();
    zedmonDescription = await getZedmonDescription(zedmonPath);
    tempDir = await Directory.current.createTemp();
    tempFilePath = '${tempDir.path}/zedmon.csv';
  });

  tearDown(() async {
    final file = File(tempFilePath);
    if (file.existsSync()) {
      file.deleteSync();
    }
  });

  // `zedmon list` should yield exactly one word, containing a serial number.
  test('zedmon list', () async {
    final result = await Process.run(zedmonPath, ['list']);
    expect(result.exitCode, equals(0));

    final regex = RegExp(r'\W+');
    expect(regex.allMatches(result.stdout).length, equals(1));
  });

  // Records 1 second of Zedmon data and validates the power calculation for
  // each line of output.
  test('zedmon record', () async {
    final result = await Process.run(
        zedmonPath, ['record', '--out', tempFilePath, '--duration', '1s']);
    expect(result.exitCode, equals(0));

    final lines = await File(tempFilePath).readAsLines();

    // Zedmon's nominal output rate is about 1500 Hz. Expecting 1400 lines
    // gives a bit of buffer for packet loss; see fxbug.dev/64161.
    expect(lines.length, greaterThan(1400));

    for (String line in lines) {
      validateZedmonCsvLine(line, zedmonDescription, 1e-4);
    }
  });

  test('zedmon record downsampled', () async {
    final result = await Process.run(zedmonPath, [
      'record',
      '--out',
      tempFilePath,
      '--duration',
      '1s',
      '--interval',
      '100ms'
    ]);
    expect(result.exitCode, equals(0));

    final lines = await File(tempFilePath).readAsLines();

    // We should see exactly 10 records, given a 100ms reporting interval over
    // a 1s duration. (Zedmon's nominal reporting interval is ~667us, so we'd
    // have to miss many consecutive packets before a downsampled packet is
    // skipped, and that would indicate a problem worth investigating.)
    expect(lines.length, equals(10));

    for (String line in lines) {
      // Power in each output record is averaged from the power derived from
      // each sample rather than computed from average shunt voltage and
      // average bus power. Consequently, the tolerance in the power calculation
      // needs to be higher here.
      validateZedmonCsvLine(line, zedmonDescription, 0.01);
    }
  });

  // Tests that the 5-second average power drops by at least 99% when the
  // relay is turned off.
  test('zedmon relay', () async {
    var result = await Process.run(zedmonPath, ['relay', 'off']);
    expect(result.exitCode, equals(0));
    sleep(Duration(seconds: 1));
    final offPower = await measureAveragePower(
        zedmonPath, tempFilePath, zedmonDescription, 5);

    result = await Process.run(zedmonPath, ['relay', 'on']);
    expect(result.exitCode, equals(0));
    sleep(Duration(seconds: 1));
    final onPower = await measureAveragePower(
        zedmonPath, tempFilePath, zedmonDescription, 5);

    expect(offPower, lessThan(0.01 * onPower));
  });
}
