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

#include "pw_system_private/log.h"

#include <array>
#include <cstddef>

#include "pw_bytes/span.h"
#include "pw_chrono/system_clock.h"
#include "pw_log/proto_utils.h"
#include "pw_log_rpc/rpc_log_drain.h"
#include "pw_log_rpc/rpc_log_drain_map.h"
#include "pw_log_tokenized/metadata.h"
#include "pw_multisink/multisink.h"
#include "pw_result/result.h"
#include "pw_sync/interrupt_spin_lock.h"
#include "pw_sync/lock_annotations.h"
#include "pw_sync/mutex.h"
#include "pw_system/config.h"
#include "pw_system_private/rpc.h"
#include "pw_tokenizer/tokenize_to_global_handler_with_payload.h"

namespace pw::system {
namespace {

using log_rpc::RpcLogDrain;

// Storage container for MultiSink used for deferred logging.
std::array<std::byte, PW_SYSTEM_LOG_BUFFER_SIZE> log_buffer;

// Buffer used to encode each log entry before saving into log buffer.
sync::InterruptSpinLock log_encode_lock;
std::array<std::byte, PW_SYSTEM_MAX_LOG_ENTRY_SIZE> log_encode_buffer
    PW_GUARDED_BY(log_encode_lock);

// To save RAM, share the mutex and buffer between drains, since drains are
// flushed sequentially.
sync::Mutex drains_mutex;
// Buffer to decode and remove entries from log buffer, to send to a drain.
std::array<std::byte, PW_SYSTEM_MAX_LOG_ENTRY_SIZE> log_decode_buffer
    PW_GUARDED_BY(drains_mutex);

std::array<RpcLogDrain, 1> drains{{
    RpcLogDrain(kDefaultChannelId,
                log_decode_buffer,
                drains_mutex,
                RpcLogDrain::LogDrainErrorHandling::kIgnoreWriterErrors),
}};

log_rpc::RpcLogDrainMap drain_map(drains);

const int64_t boot_time_count =
    pw::chrono::SystemClock::now().time_since_epoch().count();
}  // namespace

// Deferred log buffer, for storing log entries while logging_thread_ streams
// them independently.
multisink::MultiSink& GetMultiSink() {
  static multisink::MultiSink multisink(log_buffer);
  return multisink;
}

log_rpc::RpcLogDrainThread& GetLogThread() {
  static log_rpc::RpcLogDrainThread logging_thread(GetMultiSink(), drain_map);
  return logging_thread;
}

log_rpc::LogService& GetLogService() {
  static log_rpc::LogService log_service(drain_map);
  return log_service;
}

// Provides time since boot in units defined by the target's pw_chrono backend.
int64_t GetTimestamp() {
  return pw::chrono::SystemClock::now().time_since_epoch().count() -
         boot_time_count;
}

// Implementation for tokenized log handling. This will be optimized out for
// devices that only use string logging.
extern "C" void pw_tokenizer_HandleEncodedMessageWithPayload(
    pw_tokenizer_Payload payload, const uint8_t message[], size_t size_bytes) {
  log_tokenized::Metadata metadata = payload;
  const int64_t timestamp = GetTimestamp();

  std::lock_guard lock(log_encode_lock);
  Result<ConstByteSpan> encoded_log_result = log::EncodeTokenizedLog(
      metadata, message, size_bytes, timestamp, log_encode_buffer);
  if (!encoded_log_result.ok()) {
    GetMultiSink().HandleDropped();
    return;
  }
  GetMultiSink().HandleEntry(encoded_log_result.value());
}

}  // namespace pw::system
