// 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.
//
// The header provides a set of helper utils for protobuf related operations.
// The APIs may not be finalized yet.

#pragma once

#include <cstddef>
#include <string_view>

#include "pw_assert/check.h"
#include "pw_protobuf/internal/proto_integer_base.h"
#include "pw_protobuf/stream_decoder.h"
#include "pw_status/status.h"
#include "pw_status/try.h"
#include "pw_stream/interval_reader.h"
#include "pw_stream/stream.h"

namespace pw::protobuf {

// The following defines classes that represent various parsed proto integer
// types or an error code to indicate parsing failure.
//
// For normal uses, the class should be created from `class Message`. See
// comment for `class Message` for usage.

class Uint32 : public internal::ProtoIntegerBase<uint32_t> {
 public:
  using ProtoIntegerBase<uint32_t>::ProtoIntegerBase;
};

class Int32 : public internal::ProtoIntegerBase<int32_t> {
 public:
  using ProtoIntegerBase<int32_t>::ProtoIntegerBase;
};

class Sint32 : public internal::ProtoIntegerBase<int32_t> {
 public:
  using ProtoIntegerBase<int32_t>::ProtoIntegerBase;
};

class Fixed32 : public internal::ProtoIntegerBase<uint32_t> {
 public:
  using ProtoIntegerBase<uint32_t>::ProtoIntegerBase;
};

class Sfixed32 : public internal::ProtoIntegerBase<int32_t> {
 public:
  using ProtoIntegerBase<int32_t>::ProtoIntegerBase;
};

class Uint64 : public internal::ProtoIntegerBase<uint64_t> {
 public:
  using ProtoIntegerBase<uint64_t>::ProtoIntegerBase;
};

class Int64 : public internal::ProtoIntegerBase<int64_t> {
 public:
  using ProtoIntegerBase<int64_t>::ProtoIntegerBase;
};

class Sint64 : public internal::ProtoIntegerBase<int64_t> {
 public:
  using ProtoIntegerBase<int64_t>::ProtoIntegerBase;
};

class Fixed64 : public internal::ProtoIntegerBase<uint64_t> {
 public:
  using ProtoIntegerBase<uint64_t>::ProtoIntegerBase;
};

class Sfixed64 : public internal::ProtoIntegerBase<int64_t> {
 public:
  using ProtoIntegerBase<int64_t>::ProtoIntegerBase;
};

// An object that represents a parsed `bytes` field or an error code. The
// bytes are available via an stream::IntervalReader by GetBytesReader().
//
// For normal uses, the class should be created from `class Message`. See
// comment for `class Message` for usage.
class Bytes {
 public:
  Bytes() = default;
  Bytes(Status status) : reader_(status) {}
  Bytes(stream::IntervalReader reader) : reader_(reader) {}
  const stream::IntervalReader& GetBytesReader() { return reader_; }
  bool ok() { return reader_.ok(); }
  Status status() { return reader_.status(); }

  // Check whether the bytes value equals the given `bytes`.
  Result<bool> Equal(ConstByteSpan bytes);

 private:
  stream::IntervalReader reader_;
};

// An object that represents a parsed `string` field or an error code. The
// string value is available via an stream::IntervalReader by
// GetBytesReader().
//
// For normal uses, the class should be created from `class Message`. See
// comment for `class Message` for usage.
class String : public Bytes {
 public:
  using Bytes::Bytes;

  // Check whether the string value equals the given `str`
  Result<bool> Equal(std::string_view str);
};

// Forward declaration of parser classes.
template <typename FieldType>
class RepeatedFieldParser;
template <typename FieldType>
class StringMapEntryParser;
template <typename FieldType>
class StringMapParser;
class Message;

using RepeatedBytes = RepeatedFieldParser<Bytes>;
using RepeatedStrings = RepeatedFieldParser<String>;
using RepeatedMessages = RepeatedFieldParser<Message>;
using StringToBytesMapEntry = StringMapEntryParser<Bytes>;
using StringToStringMapEntry = StringMapEntryParser<String>;
using StringToMessageMapEntry = StringMapEntryParser<Message>;
using StringToBytesMap = StringMapParser<Bytes>;
using StringToStringMap = StringMapParser<String>;
using StringToMessageMap = StringMapParser<Message>;

// Message - A helper class for parsing a proto message.
//
// Examples:
//
// message Nested {
//   string nested_str = 1;
//   bytes nested_bytes = 2;
// }
//
// message {
//   string str = 1;
//   bytes bytes = 2;
//   uint32 integer = 3
//   repeated string rep_str = 4;
//   map<string, bytes> str_to_bytes = 5;
//   Nested nested = 6;
// }
//
//   // Given a seekable `reader` that reads the top-level proto message, and
//   // a <size> that gives the size of the proto message:
//   Message message(reader, <size>);
//
//   // Prase simple basic value fields
//   String str = message.AsString(1); // string
//   Bytes bytes = message.AsBytes(2); // bytes
//   Uint32 integer = messasge_parser.AsUint32(3); // uint32 integer
//
//   // Parse repeated field `repeated string rep_str = 4;`
//   RepeatedStrings rep_str = message.AsRepeatedString(4);
//   // Iterate through the entries
//   for (String str : rep_str) {
//     ...
//   }
//
//   // Parse map field `map<string, bytes> str_to_bytes = 5;`
//   StringToBytesMap str_to_bytes = message.AsStringToBytesMap(5);
//
//   // Access the entry by a given key value
//   Bytes bytes_for_key = str_to_bytes["key"];
//
//   // Or iterate through map entries
//   for (StringToBytesMapEntry entry : str_to_bytes) {
//     String key = entry.Key();
//     Bytes value = entry.Value();
//     ...
//   }
//
//   // Parse nested message `Nested nested = 6;`
//   Message nested = message.AsMessage(6).
//   String nested_str = nested.AsString(1);
//   Bytes nested_bytes = nested.AsBytes(2);
//
//   // The `AsXXX()` methods above internally traverse all the fields to find
//   // the one with the give field number. This can be expensive if called
//   // multiple times. Therefore, whenever possible, it is recommended to use
//   // the following iteration to iterate and process each field directly.
//   for (Message::Field field : message) {
//     if (field.field_number() == 1) {
//       String str = field.As<String>();
//       ...
//     } else if (field.field_number() == 2) {
//       Bytes bytes = field.As<Bytes>();
//       ...
//     } else if (field.field_number() == 6) {
//       Message nested = field.As<Message>();
//       ...
//     }
//   }
//
// All parser objects created above internally hold the same reference
// to `reader`. Therefore it needs to maintain valid lifespan throughout the
// operations. The parser objects can work independently and without blocking
// each other. All method calls and for-iterations above are re-enterable.
class Message {
 public:
  class Field {
   public:
    uint32_t field_number() { return field_number_; }
    const stream::IntervalReader& field_reader() { return field_reader_; }

    // Create a helper parser type of `FieldType` for the field.
    // The default implementation below assumes the field is a length-delimited
    // field. Other cases such as primitive integer uint32 will be handled by
    // template specialization.
    template <typename FieldType>
    FieldType As() {
      protobuf::StreamDecoder decoder(field_reader_.Reset());
      PW_TRY(decoder.Next());
      Result<protobuf::StreamDecoder::Bounds> payload_bounds =
          decoder.GetLengthDelimitedPayloadBounds();
      PW_TRY(payload_bounds.status());
      // The bounds is relative to the given stream::IntervalReader. Convert
      // it to the interval relative to the source_reader.
      return FieldType(stream::IntervalReader(
          field_reader_.source_reader(),
          payload_bounds.value().low + field_reader_.start(),
          payload_bounds.value().high + field_reader_.start()));
    }

   private:
    Field() = default;
    Field(stream::IntervalReader reader, uint32_t field_number)
        : field_reader_(reader), field_number_(field_number) {}

    stream::IntervalReader field_reader_;
    uint32_t field_number_;

    friend class Message;
  };

  class iterator {
   public:
    iterator& operator++();

    iterator operator++(int) {
      iterator iter = *this;
      this->operator++();
      return iter;
    }

    Field operator*() { return current_; }
    Field* operator->() { return &current_; }
    bool operator!=(const iterator& other) const { return !(*this == other); }

    bool operator==(const iterator& other) const {
      return eof_ == other.eof_ && reader_ == other.reader_;
    }

   private:
    stream::IntervalReader reader_;
    bool eof_ = false;
    Field current_;

    iterator(stream::IntervalReader reader) : reader_(reader) {
      this->operator++();
    }

    friend class Message;
  };

  Message() = default;
  Message(Status status) : reader_(status) {}
  Message(stream::IntervalReader reader) : reader_(reader) {}
  Message(stream::SeekableReader& proto_source, size_t size)
      : reader_(proto_source, 0, size) {}

  // Parse a sub-field in the message given by `field_number` as bytes.
  Bytes AsBytes(uint32_t field_number) { return As<Bytes>(field_number); }

  // Parse a sub-field in the message given by `field_number` as string.
  String AsString(uint32_t field_number) { return As<String>(field_number); }

  // Parse a sub-field in the message given by `field_number` as one of the
  // proto integer type.
  Int32 AsInt32(uint32_t field_number) { return As<Int32>(field_number); }
  Sint32 AsSint32(uint32_t field_number) { return As<Sint32>(field_number); }
  Uint32 AsUint32(uint32_t field_number) { return As<Uint32>(field_number); }
  Fixed32 AsFixed32(uint32_t field_number) { return As<Fixed32>(field_number); }
  Int64 AsInt64(uint32_t field_number) { return As<Int64>(field_number); }
  Sint64 AsSint64(uint32_t field_number) { return As<Sint64>(field_number); }
  Uint64 AsUint64(uint32_t field_number) { return As<Uint64>(field_number); }
  Fixed64 AsFixed64(uint32_t field_number) { return As<Fixed64>(field_number); }

  Sfixed32 AsSfixed32(uint32_t field_number) {
    return As<Sfixed32>(field_number);
  }

  Sfixed64 AsSfixed64(uint32_t field_number) {
    return As<Sfixed64>(field_number);
  }

  // Parse a sub-field in the message given by `field_number` as another
  // message.
  Message AsMessage(uint32_t field_number) { return As<Message>(field_number); }

  // Parse a sub-field in the message given by `field_number` as `repeated
  // string`.
  RepeatedBytes AsRepeatedBytes(uint32_t field_number);

  // Parse a sub-field in the message given by `field_number` as `repeated
  // string`.
  RepeatedStrings AsRepeatedStrings(uint32_t field_number);

  // Parse a sub-field in the message given by `field_number` as `repeated
  // message`.
  RepeatedMessages AsRepeatedMessages(uint32_t field_number);

  // Parse a sub-field in the message given by `field_number` as `map<string,
  // message>`.
  StringToMessageMap AsStringToMessageMap(uint32_t field_number);

  // Parse a sub-field in the message given by `field_number` as
  // `map<string, bytes>`.
  StringToBytesMap AsStringToBytesMap(uint32_t field_number);

  // Parse a sub-field in the message given by `field_number` as
  // `map<string, string>`.
  StringToStringMap AsStringToStringMap(uint32_t field_number);

  // Convert the message to a Bytes that represents the raw bytes of this
  // message. This can be used to obatained the serialized wire-format of the
  // message.
  Bytes ToBytes() { return Bytes(reader_.Reset()); }

  bool ok() { return reader_.ok(); }
  Status status() { return reader_.status(); }
  iterator begin();
  iterator end();

  // Parse a field given by `field_number` as the target parser type
  // `FieldType`.
  //
  // Note: This method assumes that the message has only 1 field with the given
  // <field_number>. It returns the first matching it find. It does not perform
  // value overridding or string concatenation for multiple fields with the same
  // <field_number>.
  //
  // Since the method needs to traverse all fields, it can be inefficient if
  // called multiple times exepcially on slow reader.
  template <typename FieldType>
  FieldType As(uint32_t field_number) {
    for (Field field : *this) {
      if (field.field_number() == field_number) {
        return field.As<FieldType>();
      }
    }

    return FieldType(Status::NotFound());
  }

  template <typename FieldType>
  RepeatedFieldParser<FieldType> AsRepeated(uint32_t field_number) {
    return RepeatedFieldParser<FieldType>(*this, field_number);
  }

  template <typename FieldParser>
  StringMapParser<FieldParser> AsStringMap(uint32_t field_number) {
    return StringMapParser<FieldParser>(*this, field_number);
  }

 private:
  stream::IntervalReader reader_;

  // Consume the current field. If the field has already been processed, i.e.
  // by calling one of the Read..() method, nothing is done. After calling this
  // method, the reader will be pointing either to the start of the next
  // field (i.e. the starting offset of the field key), or the end of the
  // stream. The method is for use by Message for computing field interval.
  static Status ConsumeCurrentField(StreamDecoder& decoder) {
    return decoder.field_consumed_ ? OkStatus() : decoder.SkipField();
  }
};

// The following are template specialization for proto integer types.
template <>
Uint32 Message::Field::As<Uint32>();

template <>
Int32 Message::Field::As<Int32>();

template <>
Sint32 Message::Field::As<Sint32>();

template <>
Fixed32 Message::Field::As<Fixed32>();

template <>
Sfixed32 Message::Field::As<Sfixed32>();

template <>
Uint64 Message::Field::As<Uint64>();

template <>
Int64 Message::Field::As<Int64>();

template <>
Sint64 Message::Field::As<Sint64>();

template <>
Fixed64 Message::Field::As<Fixed64>();

template <>
Sfixed64 Message::Field::As<Sfixed64>();

// A helper for parsing `repeated` field. It implements an iterator interface
// that only iterates through the fields of a given `field_number`.
//
// For normal uses, the class should be created from `class Message`. See
// comment for `class Message` for usage.
template <typename FieldType>
class RepeatedFieldParser {
 public:
  class iterator {
   public:
    // Precondition: iter_ is not pointing to the end.
    iterator& operator++() {
      iter_++;
      MoveToNext();
      return *this;
    }

    iterator operator++(int) {
      iterator iter = *this;
      this->operator++();
      return iter;
    }

    FieldType operator*() { return current_; }
    FieldType* operator->() { return &current_; }
    bool operator!=(const iterator& other) const { return !(*this == other); }
    bool operator==(const iterator& other) const {
      return &host_ == &other.host_ && iter_ == other.iter_;
    }

   private:
    RepeatedFieldParser& host_;
    Message::iterator iter_;
    bool eof_ = false;
    FieldType current_ = FieldType(Status::Unavailable());

    iterator(RepeatedFieldParser& host, Message::iterator init_iter)
        : host_(host), iter_(init_iter), current_(Status::Unavailable()) {
      // Move to the first element of the target field number.
      MoveToNext();
    }

    void MoveToNext() {
      // Move the iterator to the next element with the target field number
      for (; iter_ != host_.message_.end(); ++iter_) {
        if (iter_->field_number() == host_.field_number_) {
          current_ = iter_->As<FieldType>();
          break;
        }
      }
    }

    friend class RepeatedFieldParser;
  };

  // `message` -- The containing message.
  // `field_number` -- The field number of the repeated field.
  RepeatedFieldParser(Message& message, uint32_t field_number)
      : message_(message), field_number_(field_number) {}

  bool ok() { return message_.ok(); }
  Status status() { return message_.status(); }
  iterator begin() { return iterator(*this, message_.begin()); }
  iterator end() { return iterator(*this, message_.end()); }

 private:
  Message& message_;
  uint32_t field_number_ = 0;
};

// A helper for pasring the entry type of map<string, <value>>.
// An entry for a proto map is essentially a message of a key(k=1) and
// value(k=2) field, i.e.:
//
// message Entry {
//   string key = 1;
//   bytes value = 2;
// }
//
// For normal uses, the class should be created from `class Message`. See
// comment for `class Message` for usage.
template <typename ValueParser>
class StringMapEntryParser {
 public:
  StringMapEntryParser(Status status) : entry_(status) {}
  StringMapEntryParser(stream::IntervalReader reader) : entry_(reader) {}
  String Key() { return entry_.AsString(kMapKeyFieldNumber); }
  ValueParser Value() { return entry_.As<ValueParser>(kMapValueFieldNumber); }

 private:
  static constexpr uint32_t kMapKeyFieldNumber = 1;
  static constexpr uint32_t kMapValueFieldNumber = 2;
  Message entry_;
};

// A helper class for parsing a string-keyed map field. i.e. map<string,
// <value>>. The template argument `ValueParser` indicates the type the value
// will be parsed as, i.e. String, Bytes, Uint32, Message etc.
//
// For normal uses, the class should be created from `class Message`. See
// comment for `class Message` for usage.
template <typename ValueParser>
class StringMapParser
    : public RepeatedFieldParser<StringMapEntryParser<ValueParser>> {
 public:
  using RepeatedFieldParser<
      StringMapEntryParser<ValueParser>>::RepeatedFieldParser;

  // Operator overload for value access of a given key.
  ValueParser operator[](std::string_view target) {
    // Iterate over all entries and find the one whose key matches `target`
    for (StringMapEntryParser<ValueParser> entry : *this) {
      String key = entry.Key();
      PW_TRY(key.status());

      // Compare key value with the given string
      Result<bool> cmp_res = key.Equal(target);
      PW_TRY(cmp_res.status());
      if (cmp_res.value()) {
        return entry.Value();
      }
    }

    return ValueParser(Status::NotFound());
  }
};

}  // namespace pw::protobuf
