// 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++() {
  // 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;
  }

  PW_CHECK(status.ok());
  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.
  PW_CHECK(ConsumeCurrentField(decoder).ok());

  // 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() {
  PW_CHECK(ok());
  return iterator(reader_.Reset());
}

Message::iterator Message::end() {
  PW_CHECK(ok());
  // 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_;
  PW_CHECK(reader_end.Seek(0, stream::Stream::Whence::kEnd).ok());
  return iterator(reader_end);
}

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
