/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "src/trace_processor/event_tracker.h"
#include "perfetto/base/utils.h"
#include "src/trace_processor/process_tracker.h"
#include "src/trace_processor/trace_processor_context.h"

#include <math.h>

namespace perfetto {
namespace trace_processor {

EventTracker::EventTracker(TraceProcessorContext* context)
    : idle_string_id_(context->storage->InternString("idle")),
      context_(context) {}

EventTracker::~EventTracker() = default;

StringId EventTracker::GetThreadNameId(uint32_t tid, base::StringView comm) {
  return tid == 0 ? idle_string_id_ : context_->storage->InternString(comm);
}

void EventTracker::PushSchedSwitch(uint32_t cpu,
                                   uint64_t timestamp,
                                   uint32_t prev_pid,
                                   uint32_t,
                                   uint32_t next_pid,
                                   base::StringView next_comm) {
  // At this stage all events should be globally timestamp ordered.
  if (timestamp < prev_timestamp_) {
    PERFETTO_ELOG("sched_switch event out of order by %.4f ms, skipping",
                  (prev_timestamp_ - timestamp) / 1e6);
    return;
  }
  prev_timestamp_ = timestamp;
  PERFETTO_DCHECK(cpu < base::kMaxCpus);

  auto* slices = context_->storage->mutable_slices();
  auto* pending_slice = &pending_sched_per_cpu_[cpu];
  if (pending_slice->storage_index < std::numeric_limits<size_t>::max()) {
    // If the this events previous pid does not match the previous event's next
    // pid, make a note of this.
    if (prev_pid != pending_slice->pid) {
      context_->storage->mutable_stats()->mismatched_sched_switch_tids++;
    }

    size_t idx = pending_slice->storage_index;
    uint64_t duration = timestamp - slices->start_ns()[idx];
    slices->set_duration(idx, duration);
  }

  StringId name_id = GetThreadNameId(next_pid, next_comm);
  auto utid =
      context_->process_tracker->UpdateThread(timestamp, next_pid, name_id);

  pending_slice->storage_index =
      slices->AddSlice(cpu, timestamp, 0 /* duration */, utid);
  pending_slice->pid = next_pid;
}

void EventTracker::PushCounter(uint64_t timestamp,
                               double value,
                               StringId name_id,
                               uint64_t ref,
                               RefType ref_type) {
  if (timestamp < prev_timestamp_) {
    PERFETTO_ELOG("counter event out of order by %.4f ms, skipping",
                  (prev_timestamp_ - timestamp) / 1e6);
    return;
  }
  prev_timestamp_ = timestamp;

  auto* counters = context_->storage->mutable_counters();
  const auto& key = CounterKey{ref, name_id};
  auto counter_it = pending_counters_per_key_.find(key);
  if (counter_it != pending_counters_per_key_.end()) {
    size_t idx = counter_it->second;
    uint64_t duration = timestamp - counters->timestamps()[idx];
    // Update duration of previously stored event.
    counters->set_duration(idx, duration);
  }

  // At this point we don't know the duration so just store 0.
  pending_counters_per_key_[key] =
      counters->AddCounter(timestamp, 0 /* duration */, name_id, value,
                           static_cast<int64_t>(ref), ref_type);
}

}  // namespace trace_processor
}  // namespace perfetto
