// 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()) {
    // Variadic macros promote float to double. Explicitly cast here to
    // acknowledge this and allow projects to use -Wdouble-promotion.
    PW_LOG_INFO("%s \"%s\": %f,",
                indent,
                encoded_name.value(),
                static_cast<double>(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
