// Copyright (c) 2019, 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 'package:logging/logging.dart';
import 'package:observatory/sample_profile.dart';
import 'package:observatory/models.dart' as M;
import 'package:observatory/service.dart' as S;

class TimelineRepositoryBase {
  static const _kStackFrames = 'stackFrames';
  static const _kTraceEvents = 'traceEvents';
  static const kTimeOriginMicros = 'timeOriginMicros';
  static const kTimeExtentMicros = 'timeExtentMicros';

  Future<void> _formatSamples(M.Isolate isolate, Map traceObject,
      Future<S.ServiceObject> cpuSamples) async {
    const kRootFrameId = 0;
    final profile = SampleProfile();
    await profile.load(
        isolate as S.ServiceObjectOwner, await cpuSamples as S.ServiceMap);
    final trie = profile.loadFunctionTree(M.ProfileTreeDirection.inclusive);
    final root = trie.root;
    int nextId = kRootFrameId;
    processFrame(FunctionCallTreeNode current, FunctionCallTreeNode? parent) {
      int id = nextId;
      ++nextId;
      current.frameId = id;
      // Skip the root.
      if (id != kRootFrameId) {
        final function = current.profileFunction.function;
        final key = '${isolate.id}-$id';
        traceObject[_kStackFrames][key] = {
          'category': 'Dart',
          'name': function.qualifiedName,
          'resolvedUrl': current.profileFunction.resolvedUrl,
          if (parent != null && parent.frameId != kRootFrameId)
            'parent': '${isolate.id}-${parent.frameId}',
        };
      }

      for (final child in current.children) {
        processFrame(child, current);
      }
    }

    processFrame(root, null);

    for (final sample in profile.samples) {
      FunctionCallTreeNode trie = sample[SampleProfile.kTimelineFunctionTrie];

      if (trie.frameId != kRootFrameId) {
        traceObject[_kTraceEvents].add({
          'ph': 'P', // kind = sample event
          'name': '', // Blank to keep about:tracing happy
          'pid': profile.pid,
          'tid': sample['tid'],
          'ts': sample['timestamp'],
          'cat': 'Dart',
          'sf': '${isolate.id}-${trie.frameId}',
        });
      }
    }
  }

  Future<Map> getCpuProfileTimeline(M.VMRef ref,
      {int? timeOriginMicros, int? timeExtentMicros}) async {
    final S.VM vm = ref as S.VM;
    final traceObject = <String, dynamic>{
      _kStackFrames: {},
      _kTraceEvents: [],
    };

    await Future.wait(vm.isolates.map((isolate) {
      final samples = vm.invokeRpc('getCpuSamples', {
        'isolateId': isolate.id,
        if (timeOriginMicros != null) kTimeOriginMicros: timeOriginMicros,
        if (timeExtentMicros != null) kTimeExtentMicros: timeExtentMicros,
      });
      return _formatSamples(isolate, traceObject, samples);
    }));

    return traceObject;
  }

  Future<Map> getTimeline(M.VMRef ref) async {
    final S.VM vm = ref as S.VM;
    final S.ServiceMap vmTimelineResponse =
        await vm.invokeRpc('getVMTimeline', {}) as S.ServiceMap;
    final timeOriginMicros = vmTimelineResponse[kTimeOriginMicros];
    final timeExtentMicros = vmTimelineResponse[kTimeExtentMicros];
    var traceObject = <dynamic, dynamic>{
      _kStackFrames: {},
      _kTraceEvents: [],
    };
    try {
      final cpuProfile = await getCpuProfileTimeline(
        vm,
        timeOriginMicros: timeOriginMicros,
        timeExtentMicros: timeExtentMicros,
      );
      traceObject = cpuProfile;
    } on S.ServerRpcException catch (e) {
      if (e.code != S.ServerRpcException.kFeatureDisabled) {
        rethrow;
      }
      Logger.root.info(
          "CPU profiler is disabled. Creating timeline without CPU profile.");
    }
    traceObject[_kTraceEvents].addAll(vmTimelineResponse[_kTraceEvents]);
    return traceObject;
  }
}
