// 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_protobuf/message.h"

#include <cstddef>

#include "pw_protobuf/serialized_size.h"
#include "pw_protobuf/stream_decoder.h"
#include "pw_result/result.h"
#include "pw_status/status_with_size.h"
#include "pw_stream/interval_reader.h"
#include "pw_stream/stream.h"

namespace pw::protobuf {

template <>
Uint32 Message::Field::As<Uint32>() {
  protobuf::StreamDecoder decoder(field_reader_.Reset());
  PW_TRY(decoder.Next());
  return decoder.ReadUint32();
}

template <>
Int32 Message::Field::As<Int32>() {
  protobuf::StreamDecoder decoder(field_reader_.Reset());
  PW_TRY(decoder.Next());
  return decoder.ReadInt32();
}

template <>
Sint32 Message::Field::As<Sint32>() {
  protobuf::StreamDecoder decoder(field_reader_.Reset());
  PW_TRY(decoder.Next());
  return decoder.ReadSint32();
}

template <>
Fixed32 Message::Field::As<Fixed32>() {
  protobuf::StreamDecoder decoder(field_reader_.Reset());
  PW_TRY(decoder.Next());
  return decoder.ReadFixed32();
}

template <>
Sfixed32 Message::Field::As<Sfixed32>() {
  protobuf::StreamDecoder decoder(field_reader_.Reset());
  PW_TRY(decoder.Next());
  return decoder.ReadSfixed32();
}

template <>
Uint64 Message::Field::As<Uint64>() {
  protobuf::StreamDecoder decoder(field_reader_.Reset());
  PW_TRY(decoder.Next());
  return decoder.ReadUint64();
}

template <>
Int64 Message::Field::As<Int64>() {
  protobuf::StreamDecoder decoder(field_reader_.Reset());
  PW_TRY(decoder.Next());
  return decoder.ReadInt64();
}

template <>
Sint64 Message::Field::As<Sint64>() {
  protobuf::StreamDecoder decoder(field_reader_.Reset());
  PW_TRY(decoder.Next());
  return decoder.ReadSint64();
}

template <>
Fixed64 Message::Field::As<Fixed64>() {
  protobuf::StreamDecoder decoder(field_reader_.Reset());
  PW_TRY(decoder.Next());
  return decoder.ReadFixed64();
}

template <>
Sfixed64 Message::Field::As<Sfixed64>() {
  protobuf::StreamDecoder decoder(field_reader_.Reset());
  PW_TRY(decoder.Next());
  return decoder.ReadSfixed64();
}

template <>
Float Message::Field::As<Float>() {
  protobuf::StreamDecoder decoder(field_reader_.Reset());
  PW_TRY(decoder.Next());
  return decoder.ReadFloat();
}

template <>
Double Message::Field::As<Double>() {
  protobuf::StreamDecoder decoder(field_reader_.Reset());
  PW_TRY(decoder.Next());
  return decoder.ReadDouble();
}

template <>
Bool Message::Field::As<Bool>() {
  protobuf::StreamDecoder decoder(field_reader_.Reset());
  PW_TRY(decoder.Next());
  return decoder.ReadBool();
}

Result<bool> Bytes::Equal(ConstByteSpan bytes) {
  stream::IntervalReader bytes_reader = GetBytesReader();
  if (bytes_reader.interval_size() != bytes.size()) {
    return false;
  }

  std::byte buf[1];
  for (size_t i = 0; i < bytes.size();) {
    Result<ByteSpan> res = bytes_reader.Read(buf);
    PW_TRY(res.status());
    if (res.value().size() == 1) {
      if (buf[0] != bytes[i++])
        return false;
    }
  }

  return true;
}

Result<bool> String::Equal(std::string_view str) {
  return Bytes::Equal(std::as_bytes(std::span{str}));
}

Message::iterator& Message::iterator::operator++() {
  // If this is not a valid iterator, increment it to the end iterator,
  // so loop will end.
  if (!ok()) {
    reader_.Exhaust();
    eof_ = true;
    return *this;
  }

  // Store the starting offset of the field.
  size_t field_start = reader_.current();
  protobuf::StreamDecoder decoder(reader_);
  Status status = decoder.Next();
  if (status.IsOutOfRange()) {
    eof_ = true;
    return *this;
  } else if (!status.ok()) {
    // In the case of error, invalidate the iterator. We don't immediately
    // move the iterator to end(), so that calling code has a chance to catch
    // the error.
    status_ = status;
    current_ = Field(status_);
    return *this;
  }

  Result<uint32_t> field_number = decoder.FieldNumber();
  // Consume the field so that the reader will be pointing to the start
  // of the next field, which is equivalent to the end offset of the
  // current field.
  status = ConsumeCurrentField(decoder);
  if (!status.ok()) {
    status_ = status;
    current_ = Field(status_);
    return *this;
  }

  // Create a Field object with the field interval.
  current_ = Field(stream::IntervalReader(
                       reader_.source_reader(), field_start, reader_.current()),
                   field_number.value());
  return *this;
}

Message::iterator Message::begin() {
  if (!ok()) {
    return end();
  }

  return iterator(reader_.Reset());
}

Message::iterator Message::end() {
  // The end iterator is created by using an exahusted stream::IntervalReader,
  // i.e. the reader is pointing at the internval end.
  stream::IntervalReader reader_end = reader_;
  return iterator(reader_end.Exhaust());
}

RepeatedBytes Message::AsRepeatedBytes(uint32_t field_number) {
  return AsRepeated<Bytes>(field_number);
}

RepeatedFieldParser<String> Message::AsRepeatedStrings(uint32_t field_number) {
  return AsRepeated<String>(field_number);
}

RepeatedFieldParser<Message> Message::AsRepeatedMessages(
    uint32_t field_number) {
  return AsRepeated<Message>(field_number);
}

StringMapParser<Message> Message::AsStringToMessageMap(uint32_t field_number) {
  return AsStringMap<Message>(field_number);
}

StringMapParser<Bytes> Message::AsStringToBytesMap(uint32_t field_number) {
  return AsStringMap<Bytes>(field_number);
}

StringMapParser<String> Message::AsStringToStringMap(uint32_t field_number) {
  return AsStringMap<String>(field_number);
}

}  // namespace pw::protobuf
