// Copyright 2020 The Pigweed Authors
//
// 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
//
//     https://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.
//==============================================================================
// ninja -C out/host trace_sample
// ./out/host/obj/pw_trace_tokenized/trace_sample
// python pw_trace_tokenized/py/trace.py -i out1.bin -o trace.json
//       ./out/host/obj/pw_trace_tokenized/trace_sample
#include <stdio.h>

#include <array>
#include <chrono>

#include "pw_ring_buffer/prefixed_entry_ring_buffer.h"
#include "pw_trace/trace.h"

#ifndef SAMPLE_APP_SLEEP_MILLIS
#include <thread>
#define SAMPLE_APP_SLEEP_MILLIS(millis) \
  std::this_thread::sleep_for(std::chrono::milliseconds(millis));
#endif  // SAMPLE_APP_SLEEP_MILLIS

using namespace std::chrono;

namespace {

// Time helper function
auto start = system_clock::now();
uint32_t GetTimeSinceBootMillis() {
  auto delta = system_clock::now() - start;
  return duration_cast<milliseconds>(delta).count();
}

// Creating a very simple runnable with predictable behaviour to help with the
// example. Each Runnable, has a method ShouldRun which indicates if it has work
// to do, calling Run will then do the work.
class SimpleRunnable {
 public:
  virtual const char* Name() const = 0;
  virtual bool ShouldRun() = 0;
  virtual void Run() = 0;
  virtual ~SimpleRunnable() {}
};

// Processing module
// Uses trace_id and groups to track the multiple stages of "processing".
// These are intentionally long running so they will be processing concurrently.
// The trace ID is used to seperates these concurrent jobs.
#undef PW_TRACE_MODULE_NAME
#define PW_TRACE_MODULE_NAME "Processing"
class ProcessingTask : public SimpleRunnable {
 public:
  // Run task maintains a buffer of "jobs" which just sleeps for an amount of
  // time and reposts the job until the value is zero. This gives an async
  // behaviour where multiple of the same job are happening concurrently, and
  // also has a nesting effect of a job having many stages.
  struct Job {
    uint32_t job_id;
    uint8_t value;
  };
  struct JobBytes {
    union {
      Job job;
      std::byte bytes[sizeof(Job)];
    };
  };
  ProcessingTask() {
    // Buffer is used for the job queue.
    std::span<std::byte> buf_span = std::span<std::byte>(
        reinterpret_cast<std::byte*>(jobs_buffer_), sizeof(jobs_buffer_));
    jobs_.SetBuffer(buf_span);
  }
  const char* Name() const override { return "Processing Task"; }
  bool ShouldRun() override { return jobs_.EntryCount() > 0; }
  void Run() override {
    JobBytes job_bytes;
    size_t bytes_read;

    // Trace the job count backlog
    size_t entry_count = jobs_.EntryCount();

    // Get the next job from the queue.
    jobs_.PeekFront(job_bytes.bytes, &bytes_read);
    jobs_.PopFront();
    Job& job = job_bytes.job;

    // Process the job
    ProcessingJob(job);
    if (job.value > 0) {  // repost for more work if value > 0
      AddJobInternal(job.job_id, job.value - 1);
    } else {
      PW_TRACE_END("Job", "Process", job.job_id);
    }
    PW_TRACE_INSTANT_DATA("job_backlog_count",
                          "@pw_arg_counter",
                          &entry_count,
                          sizeof(entry_count));
  }
  void AddJob(uint32_t job_id, uint8_t value) {
    PW_TRACE_START_DATA(
        "Job", "Process", job_id, "@pw_py_struct_fmt:B", &value, sizeof(value));
    AddJobInternal(job_id, value);
  }

 private:
  static constexpr size_t kMaxJobs = 10;
  static constexpr size_t kProcessingTimePerValueMillis = 250;
  Job jobs_buffer_[kMaxJobs];
  pw::ring_buffer::PrefixedEntryRingBuffer jobs_{false};

  void ProcessingJob(const Job& job) {
    PW_TRACE_FUNCTION("Process", job.job_id);
    for (uint8_t i = 0; i < job.value; i++) {
      PW_TRACE_SCOPE("loop", "Process", job.job_id);
      SAMPLE_APP_SLEEP_MILLIS(50);  // Fake processing time
      SomeProcessing(&job);
    }
  }

  void SomeProcessing(const Job* job) {
    uint32_t id = job->job_id;
    PW_TRACE_FUNCTION("Process", id);
    SAMPLE_APP_SLEEP_MILLIS(
        kProcessingTimePerValueMillis);  // Fake processing time
  }
  void AddJobInternal(uint32_t job_id, uint8_t value) {
    JobBytes job{.job = {.job_id = job_id, .value = value}};
    jobs_.PushBack(job.bytes);
  }
} processing_task;

// Input Module
// Uses traces in groups to indicate the different steps of reading the new
// event.
// Uses an instant data event to dump the read sample into the trace.
#undef PW_TRACE_MODULE_NAME
#define PW_TRACE_MODULE_NAME "Input"
class InputTask : public SimpleRunnable {
  // Every second generate new output
 public:
  const char* Name() const override { return "Input Task"; }
  bool ShouldRun() override {
    return (GetTimeSinceBootMillis() - last_run_time_ > kRunInterval);
  }
  void Run() override {
    last_run_time_ = GetTimeSinceBootMillis();
    PW_TRACE_FUNCTION("Input");
    SAMPLE_APP_SLEEP_MILLIS(50);
    uint8_t value = GetValue();
    PW_TRACE_INSTANT_DATA("value", "@pw_arg_counter", &value, sizeof(value));
    processing_task.AddJob(sample_count_, value);
    sample_count_++;
  }

 private:
  uint8_t GetValue() {
    PW_TRACE_FUNCTION("Input");
    SAMPLE_APP_SLEEP_MILLIS(100);  // Fake processing time
    return sample_count_ % 4 + 1;
  }
  size_t sample_count_ = 0;
  uint32_t last_run_time_ = 0;
  static constexpr uint32_t kRunInterval = 1000;
} input_task;

// Simple main loop acting as the "Kernel"
// Uses simple named trace durations to indicate which task/job is running
#undef PW_TRACE_MODULE_NAME
#define PW_TRACE_MODULE_NAME "Kernel"
void StartFakeKernel() {
  std::array<SimpleRunnable*, 2> tasks = {&input_task, &processing_task};

  bool idle = false;
  while (true) {
    bool have_any_run = false;
    for (auto& task : tasks) {
      if (task->ShouldRun()) {
        if (idle) {
          PW_TRACE_END("Idle", "Idle");
          idle = false;
        }
        have_any_run = true;
        // The task name is not a string literal and is therefore put in the
        // data section, so it can also work with tokenized trace.
        PW_TRACE_START_DATA(
            "Running", "@pw_arg_group", task->Name(), strlen(task->Name()));
        task->Run();
        PW_TRACE_END_DATA(
            "Running", "@pw_arg_group", task->Name(), strlen(task->Name()));
      }
    }
    if (!idle && !have_any_run) {
      PW_TRACE_START("Idle", "Idle");
      idle = true;
    }
  }
}

}  // namespace

void RunTraceSampleApp() { StartFakeKernel(); }