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

#include "pw_metric/metric.h"

#include <array>
#include <span>

#include "pw_assert/check.h"
#include "pw_log/log.h"
#include "pw_tokenizer/base64.h"

namespace pw::metric {
namespace {

template <typename T>
std::span<const std::byte> AsSpan(const T& t) {
  return std::span<const std::byte>(reinterpret_cast<const std::byte*>(&t),
                                    sizeof(t));
}

// A convenience class to encode a token as base64 while managing the storage.
// TODO(keir): Consider putting this into upstream pw_tokenizer.
struct Base64EncodedToken {
  Base64EncodedToken(Token token) {
    int encoded_size = tokenizer::PrefixedBase64Encode(AsSpan(token), data);
    data[encoded_size] = 0;
  }

  const char* value() { return data.data(); }
  std::array<char, 16> data;
};

const char* Indent(int level) {
  static const char* kWhitespace8 = "        ";
  level = std::min(level, 4);
  return kWhitespace8 + 8 - 2 * level;
}

}  // namespace

// Enable easier registration when used as a member.
Metric::Metric(Token name, float value, IntrusiveList<Metric>& metrics)
    : Metric(name, value) {
  metrics.push_front(*this);
}
Metric::Metric(Token name, uint32_t value, IntrusiveList<Metric>& metrics)
    : Metric(name, value) {
  metrics.push_front(*this);
}

float Metric::as_float() const {
  PW_DCHECK(is_float());
  return float_;
}

uint32_t Metric::as_int() const {
  PW_DCHECK(is_int());
  return uint_;
}

void Metric::Increment(uint32_t amount) {
  PW_DCHECK(is_int());
  uint_ += amount;
}

void Metric::SetInt(uint32_t value) {
  PW_DCHECK(is_int());
  uint_ = value;
}

void Metric::SetFloat(float value) {
  PW_DCHECK(is_float());
  float_ = value;
}

void Metric::Dump(int level) {
  Base64EncodedToken encoded_name(name());
  const char* indent = Indent(level);
  if (is_float()) {
    PW_LOG_INFO("%s \"%s\": %f,", indent, encoded_name.value(), as_float());
  } else {
    PW_LOG_INFO("%s \"%s\": %u,",
                indent,
                encoded_name.value(),
                static_cast<unsigned int>(as_int()));
  }
}

void Metric::Dump(IntrusiveList<Metric>& metrics, int level) {
  for (auto& m : metrics) {
    m.Dump(level);
  }
}

Group::Group(Token name) : name_(name) {}

Group::Group(Token name, IntrusiveList<Group>& groups) : name_(name) {
  groups.push_front(*this);
}

void Group::Dump(int level) {
  Base64EncodedToken encoded_name(name());
  const char* indent = Indent(level);
  PW_LOG_INFO("%s \"%s\": {", indent, encoded_name.value());
  Group::Dump(children(), level + 1);
  Metric::Dump(metrics(), level + 1);
  PW_LOG_INFO("%s }", indent);
}

void Group::Dump(IntrusiveList<Group>& groups, int level) {
  for (auto& group : groups) {
    group.Dump(level);
  }
}

}  // namespace pw::metric
