// Copyright 2018 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.

#include <lib/fxl/logging.h>

#include "garnet/lib/cpuperf/events.h"

#include "verify_test.h"

class ProgrammableCounterVerifier : public Verifier {
 public:
  static std::unique_ptr<Verifier> Create(
      const cpuperf::SessionResultSpec* spec) {
    return std::make_unique<ProgrammableCounterVerifier>(spec);
  }

  ProgrammableCounterVerifier(const cpuperf::SessionResultSpec* spec)
      : Verifier(spec) {
    const cpuperf::EventDetails* details;

    bool rc __UNUSED =
      cpuperf::LookupEventByName("arch", "llc_references", &details);
    FXL_DCHECK(rc);
    llc_references_id_ = details->id;

    rc = cpuperf::LookupEventByName("arch", "llc_misses", &details);
    FXL_DCHECK(rc);
    llc_misses_id_ = details->id;

    rc = cpuperf::LookupEventByName("arch", "branches_retired",
                                    &details);
    FXL_DCHECK(rc);
    branches_retired_id_ = details->id;

    rc = cpuperf::LookupEventByName("arch", "branch_misses_retired",
                                    &details);
    FXL_DCHECK(rc);
    branch_misses_retired_id_ = details->id;
  }

 private:
  bool VerifyRecord(const cpuperf::SampleRecord& record) override {
    if (record.header->event == llc_references_id_) {
      ++llc_references_count_;
    } else if (record.header->event == llc_misses_id_) {
      ++llc_misses_count_;
    } else if (record.header->event == branches_retired_id_) {
      ++branches_retired_count_;
    } else if (record.header->event == branch_misses_retired_id_) {
      ++branch_misses_retired_count_;
    }
    return true;
  }

  bool VerifyTrace(const RecordCounts& counts) override {
    bool pass = true;
    if (llc_references_count_ == 0) {
      FXL_LOG(ERROR) << "Missing llc_references events";
      pass = false;
    }
    if (llc_misses_count_ == 0) {
      FXL_LOG(ERROR) << "Missing llc_misses events";
      pass = false;
    }
    if (branches_retired_count_ == 0) {
      FXL_LOG(ERROR) << "Missing branches_retired events";
      pass = false;
    }
    if (branch_misses_retired_count_ == 0) {
      FXL_LOG(ERROR) << "Missing branch_misses_retired events";
      pass = false;
    }
    return pass;
  }

  // Ids of the events we should see.
  cpuperf_event_id_t llc_references_id_;
  cpuperf_event_id_t llc_misses_id_;
  cpuperf_event_id_t branches_retired_id_;
  cpuperf_event_id_t branch_misses_retired_id_;

  // Counts of the events we should see;
  cpuperf_event_id_t llc_references_count_ = 0;
  cpuperf_event_id_t llc_misses_count_ = 0;
  cpuperf_event_id_t branches_retired_count_ = 0;
  cpuperf_event_id_t branch_misses_retired_count_ = 0;
};

const TestSpec kProgrammableCounterSpec = {
  "programmable-counters",
  &ProgrammableCounterVerifier::Create,
};
