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

#pragma once

#include <cstdint>
#include <span>

#include "pw_bytes/span.h"
#include "pw_status/status.h"

namespace pw::dump {

// Size, in bytes, of the resulting string after converting an address to a
// UTF-8 encoded hex representation. This constant depends on the size
// a of a pointer.
//
// Example (32-bit):
//   0x0000F00D
//
// Note: the +2 accounts for the "0x" prefix.
constexpr const size_t kHexAddrStringSize = sizeof(uintptr_t) * 2 + 2;

// It is strongly recommended NOT to directly depend on this dump format;
// pw_hex_dump does NOT guarantee stability for the output format, but strives
// to remain xxd compatible.
//
// Default:
//   Offs.  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  Text
//   0000: A4 CC 32 62 9B 46 38 1A 23 1A 2A 7A BC E2 40 A0  ..2b.F8.#.*z..@.
//   0010: FF 33 E5 2B 9E 9F 6B 3C BE 9B 89 3C 7E 4A 7A 48  .3.+..k<...<~JzH
//   0020: 18                                               .
//
// Example 1 (32-bit machine, group_every=4, prefix_mode=kAbsolute,
//            bytes_per_line = 8):
//   Address      0        4        Text
//   0x20000000: A4CC3262 9B46381A  ..2b.F8.
//   0x20000008: 231A2A7A BCE240A0  #.*z..@.
//   0x20000010: FF33E52B 9E9F6B3C  .3.+..k<
//   0x20000018: BE9B893C 7E4A7A48  ...<~JzH
//   0x20000020: 18                 .
//
// Example 2 (group_every=1, bytes_per_line = 16):
//   Offs.  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
//   0000: A4 CC 32 62 9B 46 38 1A 23 1A 2A 7A BC E2 40 A0
//   0010: FF 33 E5 2B 9E 9F 6B 3C BE 9B 89 3C 7E 4A 7A 48
//   0020: 18
//
// Example 3 (group_every=0, prefix_mode=kNone, show_header=false,
//            show_ascii=false):
//   A4CC32629B46381A231A2A7ABCE240A0
//   FF33E52B9E9F6B3CBE9B893C7E4A7A48
//   18
class FormattedHexDumper {
 public:
  enum AddressMode {
    kDisabled = 0,
    kOffset = 1,
    kAbsolute = 2,
  };

  struct Flags {
    // Sets the number of source data bytes to print in each formatted line.
    uint8_t bytes_per_line : 8;

    // Inserts a space every N bytes for readability. Note that this is in
    // number of bytes converted to characters. Set to zero to disable. I.e. a
    // value of 2 results in:
    //   0x00000000: 0102 0304 0506 0708
    uint8_t group_every : 8;

    // Show or hide ascii interpretation of binary data.
    bool show_ascii : 1;

    // Show descriptive column headers.
    bool show_header : 1;

    // Prefix each line of the dump with an offset or absolute address.
    AddressMode prefix_mode : 2;
  };

  Flags flags = {.bytes_per_line = 16,
                 .group_every = 1,
                 .show_ascii = true,
                 .show_header = true,
                 .prefix_mode = AddressMode::kOffset};

  FormattedHexDumper() = default;
  FormattedHexDumper(std::span<char> dest) { SetLineBuffer(dest); }
  FormattedHexDumper(std::span<char> dest, Flags config_flags)
      : flags(config_flags) {
    SetLineBuffer(dest);
  }

  // TODO(pwbug/218): Add iterator support.

  // Set the destination buffer that the hex dumper will write to line-by-line.
  //
  // Returns:
  //   RESOURCE_EXHAUSTED - The buffer was set, but is too small to fit the
  //     current formatting configuration.
  //   INVALID_ARGUMENT - The destination buffer is invalid (nullptr or zero-
  //     length).
  Status SetLineBuffer(std::span<char> dest);

  // Begin dumping the provided data. Does NOT populate the line buffer with
  // a string, simply resets the statefulness to track this buffer.
  //
  // Returns:
  //   OK - Ready to begin dump.
  //   INVALID_ARGUMENT - The source data starts at null, but has been set.
  //   FAILED_PRECONDITION - Line buffer too small to hold current formatting
  //     settings.
  Status BeginDump(ConstByteSpan data);

  // Dumps a single line to the line buffer.
  //
  // Example usage:
  //
  //   std::array<char, 80> temp;
  //   FormattedHexDumper hex_dumper(temp);
  //   hex_dumper.BeginDump(my_data);
  //   while(hex_dumper.DumpLine().ok()) {
  //     LOG_INFO("%s", temp.data());
  //   }
  //
  // Returns:
  //   OK - A line has been written to the line buffer.
  //   RESOURCE_EXHAUSTED - All the data has been dumped.
  //   FAILED_PRECONDITION - Destination line buffer is too small to fit current
  //     formatting configuration.
  Status DumpLine();

 private:
  Status ValidateBufferSize();
  Status PrintFormatHeader();

  size_t current_offset_;
  std::span<char> dest_;
  ConstByteSpan source_data_;
};

// Dumps a uintptr_t to a character buffer as a hex address. This may be useful
// to print out an address in a generalized way when %z and %p aren't supported
// by a standard library implementation. The destination buffer MUST be large
// enough to hold kHexAddrStringSize + 1 (null terminator) bytes.
//
// Example (64-bit):
//   0x000000000022b698
// Example (32-bit):
//   0x70000000
//
// Returns:
//   OK - Address has been written to the buffer.
//   INVALID_ARGUMENT - The destination buffer is invalid (nullptr).
//   RESOURCE_EXHAUSTED - The destination buffer is too small. No data written.
Status DumpAddr(std::span<char> dest, uintptr_t addr);
inline Status DumpAddr(std::span<char> dest, const void* ptr) {
  uintptr_t addr = reinterpret_cast<uintptr_t>(ptr);
  return DumpAddr(dest, addr);
}

}  // namespace pw::dump
