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

#ifndef RUNTIME_VM_TIMELINE_ANALYSIS_H_
#define RUNTIME_VM_TIMELINE_ANALYSIS_H_

#include "vm/growable_array.h"
#include "vm/timeline.h"

namespace dart {

class TimelineAnalysisThread : public ZoneAllocated {
 public:
  explicit TimelineAnalysisThread(ThreadId id);
  ~TimelineAnalysisThread();

  ThreadId id() const { return id_; }

  intptr_t NumBlocks() const { return blocks_.length(); }

  TimelineEventBlock* At(intptr_t i) const { return blocks_.At(i); }

 private:
  void AddBlock(TimelineEventBlock* block);
  void Finalize();

  const ThreadId id_;
  ZoneGrowableArray<TimelineEventBlock*> blocks_;

  friend class TimelineAnalysis;
};


class TimelineAnalysisThreadEventIterator : public ValueObject {
 public:
  explicit TimelineAnalysisThreadEventIterator(TimelineAnalysisThread* thread);
  ~TimelineAnalysisThreadEventIterator();

  void Reset(TimelineAnalysisThread* thread);

  bool HasNext() const;

  TimelineEvent* Next();

 private:
  TimelineAnalysisThread* thread_;
  TimelineEvent* current_;
  intptr_t block_cursor_;
  intptr_t event_cursor_;
};


// Base of all timeline analysis classes. Base functionality:
// - discovery of all thread ids in a recording.
// - collecting all ThreadEventBlocks by thread id.
class TimelineAnalysis : public ValueObject {
 public:
  TimelineAnalysis(Zone* zone,
                   Isolate* isolate,
                   TimelineEventRecorder* recorder);
  ~TimelineAnalysis();

  void BuildThreads();

  intptr_t NumThreads() const { return threads_.length(); }

  TimelineAnalysisThread* At(intptr_t i) const { return threads_[i]; }

  TimelineAnalysisThread* GetThread(ThreadId tid);

  bool has_error() const { return has_error_; }

  const char* error_msg() const { return error_msg_; }

 protected:
  TimelineAnalysisThread* GetOrAddThread(ThreadId tid);

  void DiscoverThreads();
  void FinalizeThreads();

  void SetError(const char* format, ...);

  Zone* zone_;
  Isolate* isolate_;
  TimelineEventRecorder* recorder_;
  bool has_error_;
  const char* error_msg_;

  ZoneGrowableArray<TimelineAnalysisThread*> threads_;
};


class TimelineLabelPauseInfo : public ZoneAllocated {
 public:
  explicit TimelineLabelPauseInfo(const char* name);

  const char* name() const { return name_; }

  int64_t inclusive_micros() const { return inclusive_micros_; }

  int64_t exclusive_micros() const { return exclusive_micros_; }

  int64_t max_inclusive_micros() const { return max_inclusive_micros_; }

  int64_t max_exclusive_micros() const { return max_exclusive_micros_; }

 private:
  // Adjusts |inclusive_micros_| and |exclusive_micros_| by |micros|.
  // Also, may adjust, max_inclusive_micros_.
  void OnPush(int64_t micros, bool already_on_stack);

  // Adjusts |exclusive_micros_| by |exclusive_micros|.
  // Also, may adjust |max_exclusive_micros_|.
  void OnPop(int64_t exclusive_micros);

  // Adjusts |inclusive_micros_| and |exclusive_micros_| by |micros|.
  // Also, may adjust, |max_inclusive_micros_|.
  void OnBeginPop(int64_t inclusive_micros,
                  int64_t exclusive_micros,
                  bool already_on_stack);

  void UpdateInclusiveMicros(int64_t inclusive_micros, bool already_on_stack);
  void UpdateExclusiveMicros(int64_t exclusive_micros);

  // Adjust inclusive micros.
  void add_inclusive_micros(int64_t delta_micros) {
    inclusive_micros_ += delta_micros;
    ASSERT(inclusive_micros_ >= 0);
  }

  // Adjust exclusive micros.
  void add_exclusive_micros(int64_t delta_micros) {
    exclusive_micros_ += delta_micros;
    ASSERT(exclusive_micros_ >= 0);
  }

  void Aggregate(const TimelineLabelPauseInfo* thread_pause_info);

  const char* name_;
  int64_t inclusive_micros_;
  int64_t exclusive_micros_;
  int64_t max_inclusive_micros_;
  int64_t max_exclusive_micros_;

  friend class TimelinePauses;
  friend class TimelinePauseTrace;
};


class TimelinePauses : public TimelineAnalysis {
 public:
  TimelinePauses(Zone* zone, Isolate* isolate, TimelineEventRecorder* recorder);

  void Setup();

  void CalculatePauseTimesForThread(ThreadId tid);

  TimelineLabelPauseInfo* GetLabelPauseInfo(const char* name) const;

  int64_t InclusiveTime(const char* name) const;
  int64_t ExclusiveTime(const char* name) const;
  int64_t MaxInclusiveTime(const char* name) const;
  int64_t MaxExclusiveTime(const char* name) const;

  intptr_t NumPauseInfos() const { return labels_.length(); }

  const TimelineLabelPauseInfo* PauseInfoAt(intptr_t i) const {
    return labels_.At(i);
  }

 private:
  struct StackItem {
    TimelineEvent* event;
    TimelineLabelPauseInfo* pause_info;
    int64_t exclusive_micros;
  };

  void ProcessThread(TimelineAnalysisThread* thread);
  bool CheckStack(TimelineEvent* event);
  void PopFinishedDurations(int64_t start);
  void PopBegin(const char* label, int64_t end);
  void Push(TimelineEvent* event);
  bool IsLabelOnStack(const char* label) const;
  intptr_t StackDepth() const;
  StackItem& GetStackTop();
  TimelineLabelPauseInfo* GetOrAddLabelPauseInfo(const char* name);

  ZoneGrowableArray<StackItem> stack_;
  ZoneGrowableArray<TimelineLabelPauseInfo*> labels_;
};


class TimelinePauseTrace : public ValueObject {
 public:
  TimelinePauseTrace();
  ~TimelinePauseTrace();

  void Print();

 private:
  TimelineLabelPauseInfo* GetOrAddLabelPauseInfo(const char* name);
  void Aggregate(const TimelineLabelPauseInfo* thread_pause_info);
  void PrintPauseInfo(const TimelineLabelPauseInfo* pause_info);

  ZoneGrowableArray<TimelineLabelPauseInfo*> isolate_labels_;
};

}  // namespace dart

#endif  // RUNTIME_VM_TIMELINE_ANALYSIS_H_
