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

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

import 'benchmark_base.dart';
import 'measurement.dart';
import 'score_emitter.dart';

class PerfBenchmarkBase extends BenchmarkBase {
  late final Directory fifoDir;
  late final String perfControlFifo;
  late final RandomAccessFile openedFifo;
  late final String perfControlAck;
  late final RandomAccessFile openedAck;
  late final Process perfProcess;
  late final List<String> perfProcessArgs;

  PerfBenchmarkBase(
    super.name, {
    ScoreEmitterV2 super.emitter = const PrintEmitterV2(),
  });

  ScoreEmitterV2 get _emitterV2 => emitter as ScoreEmitterV2;

  Future<void> _createFifos() async {
    perfControlFifo = '${fifoDir.path}/perf_control_fifo';
    perfControlAck = '${fifoDir.path}/perf_control_ack';
    for (final path in [perfControlFifo, perfControlAck]) {
      final fifoResult = await Process.run('mkfifo', [path]);
      if (fifoResult.exitCode != 0) {
        throw ProcessException(
          'mkfifo',
          [path],
          'Cannot create fifo: ${fifoResult.stderr}',
          fifoResult.exitCode,
        );
      }
    }
  }

  Future<void> _startPerfStat() async {
    await _createFifos();
    perfProcessArgs = [
      'stat',
      '--delay=-1',
      '--control=fifo:$perfControlFifo,$perfControlAck',
      '-x\\t',
      '--pid=$pid',
    ];
    perfProcess = await Process.start('perf', perfProcessArgs);
  }

  void _enablePerf() {
    openedFifo = File(perfControlFifo).openSync(mode: FileMode.writeOnly);
    openedAck = File(perfControlAck).openSync();
    openedFifo.writeStringSync('enable\n');
    _waitForAck();
  }

  Future<void> _stopPerfStat(int totalIterations) async {
    openedFifo.writeStringSync('disable\n');
    openedFifo.closeSync();
    _waitForAck();
    openedAck.closeSync();
    perfProcess.kill(ProcessSignal.sigint);
    unawaited(perfProcess.stdout.drain());
    final lines = await perfProcess.stderr
        .transform(utf8.decoder)
        .transform(const LineSplitter())
        .toList();
    final exitCode = await perfProcess.exitCode;
    // Exit code from perf is -SIGINT when terminated with SIGINT.
    if (exitCode != 0 && exitCode != -ProcessSignal.sigint.signalNumber) {
      throw ProcessException(
        'perf',
        perfProcessArgs,
        lines.join('\n'),
        exitCode,
      );
    }

    const metrics = {'cycles': 'CpuCycles', 'page-faults': 'MajorPageFaults'};
    for (final line in lines) {
      if (line.split('\t') case [
        String counter,
        _,
        String event && ('cycles' || 'page-faults'),
        ...,
      ]) {
        _emitterV2.emit(
          name,
          double.parse(counter) / totalIterations,
          metric: metrics[event]!,
        );
      }
    }
    _emitterV2.emit(
      '$name.totalIterations',
      totalIterations.toDouble(),
      metric: 'Count',
    );
  }

  /// Measures the score for the benchmark and returns it.
  Future<double> measurePerf() async {
    Measurement result;
    setup();
    try {
      fifoDir = await Directory.systemTemp.createTemp('fifo');
      try {
        // Warmup for at least 100ms. Discard result.
        measureForImpl(warmup, 100);
        await _startPerfStat();
        try {
          _enablePerf();
          // Run the benchmark for at least 2000ms.
          result = measureForImpl(exercise, minimumMeasureDurationMillis);
          await _stopPerfStat(result.totalIterations);
        } catch (_) {
          perfProcess.kill(ProcessSignal.sigkill);
          rethrow;
        }
      } finally {
        await fifoDir.delete(recursive: true);
      }
    } finally {
      teardown();
    }
    return result.score;
  }

  Future<void> reportPerf() async {
    _emitterV2.emit(name, await measurePerf(), unit: 'us.');
  }

  void _waitForAck() {
    // Perf writes 'ack\n\x00' to the acknowledgement fifo.
    const ackLength = 'ack\n\x00'.length;
    var ack = <int>[...openedAck.readSync(ackLength)];
    while (ack.length < ackLength) {
      ack.addAll(openedAck.readSync(ackLength - ack.length));
    }
  }
}
