// Copyright 2017 Google Inc. All Rights Reserved.
//
// 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
//
//     http://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.

#define __STDC_LIMIT_MACROS

#include <inttypes.h>
#include <stdint.h>
#include <string.h>

#include "proto.h"

// This file and proto.h implement a minimal write-only protobuf runtime to be
// used with headers generated by misc/generate_proto_header.py.

// From https://github.com/google/protobuf/blob/3.0.x/src/google/protobuf/wire_format_lite.h
enum WireType {
  WIRETYPE_VARINT = 0,
  WIRETYPE_FIXED64 = 1,
  WIRETYPE_LENGTH_DELIMITED = 2,
  WIRETYPE_START_GROUP = 3,
  WIRETYPE_END_GROUP = 4,
  WIRETYPE_FIXED32 = 5,
};

static uint8_t MakeTag(int number, WireType wire_type) {
  const size_t FIELD_NUMBER_SHIFT = 3;
  return (number << FIELD_NUMBER_SHIFT) | static_cast<uint8_t>(wire_type);
}

// Based on https://github.com/google/protobuf/blob/3.0.x/src/google/protobuf/io/coded_stream.h
// Compile-time equivalent of VarintSize64().
template <uint64_t Value>
struct StaticVarintSize {
  static const int value =
      (Value < (1ULL << 7))
          ? 1
          : (Value < (1ULL << 14))
              ? 2
              : (Value < (1ULL << 21))
                  ? 3
                  : (Value < (1ULL << 28))
                      ? 4
                      : (Value < (1ULL << 35))
                          ? 5
                          : (Value < (1ULL << 42))
                              ? 6
                              : (Value < (1ULL << 49))
                                  ? 7
                                  : (Value < (1ULL << 56))
                                      ? 8
                                      : (Value < (1ULL << 63))
                                          ? 9
                                          : 10;
};

static void WriteVarint32WithType(std::ostream* output, int number,
                                  uint32_t value, WireType type) {
  uint8_t buf[StaticVarintSize<UINT32_MAX>::value + 1];
  uint8_t *target = buf;

  *target++ = MakeTag(number, type);

  while (value >= 0x80) {
    *target = static_cast<uint8_t>(value | 0x80);
    value >>= 7;
    ++target;
  }
  *target++ = static_cast<uint8_t>(value);

  output->write(reinterpret_cast<char*>(buf), target - buf);
}

void WriteVarint32NoTag(std::ostream* output, uint32_t value) {
  uint8_t buf[StaticVarintSize<UINT32_MAX>::value];
  uint8_t *target = buf;

  while (value >= 0x80) {
    *target = static_cast<uint8_t>(value | 0x80);
    value >>= 7;
    ++target;
  }
  *target++ = static_cast<uint8_t>(value);

  output->write(reinterpret_cast<char*>(buf), target - buf);
}

void WriteVarint32(std::ostream* output, int number, uint32_t value) {
  WriteVarint32WithType(output, number, value, WIRETYPE_VARINT);
}

void WriteVarint32SignExtended(std::ostream* output, int number,
                               int32_t value) {
  if (value < 0) {
    WriteVarint64(output, number, static_cast<uint64_t>(value));
  } else {
    WriteVarint32(output, number, static_cast<uint32_t>(value));
  }
}

void WriteVarint64(std::ostream* output, int number, uint64_t value) {
  uint8_t buf[StaticVarintSize<UINT64_MAX>::value + 1];
  uint8_t *target = buf;

  *target++ = MakeTag(number, WIRETYPE_VARINT);

  while (value >= 0x80) {
    *target = static_cast<uint8_t>(value | 0x80);
    value >>= 7;
    ++target;
  }
  *target++ = static_cast<uint8_t>(value);

  output->write(reinterpret_cast<char*>(buf), target - buf);
}

void WriteFixed32(std::ostream* output, int number, uint32_t value) {
  uint8_t buf[sizeof(value) + 1];
  uint8_t *target = buf;

  *target++ = MakeTag(number, WIRETYPE_FIXED32);
  memcpy(target, &value, sizeof(value));

  output->write(reinterpret_cast<char*>(buf), sizeof(buf));
}

void WriteFixed64(std::ostream* output, int number, uint64_t value) {
  uint8_t buf[sizeof(value) + 1];
  uint8_t *target = buf;

  *target++ = MakeTag(number, WIRETYPE_FIXED64);
  memcpy(target, &value, sizeof(value));

  output->write(reinterpret_cast<char*>(buf), sizeof(buf));
}

void WriteString(std::ostream* output, int number, const std::string& value) {
  WriteLengthDelimited(output, number, value.size());
  output->write(value.data(), value.size());
}

void WriteLengthDelimited(std::ostream* output, int number, size_t size) {
  WriteVarint32WithType(output, number, size, WIRETYPE_LENGTH_DELIMITED);
}
