// Copyright 2021 Google LLC
//
// 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 "dice/cbor_writer.h"

#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>

enum CborType {
  CBOR_TYPE_UINT = 0,
  CBOR_TYPE_NINT = 1,
  CBOR_TYPE_BSTR = 2,
  CBOR_TYPE_TSTR = 3,
  CBOR_TYPE_ARRAY = 4,
  CBOR_TYPE_MAP = 5,
  // Type 6, tags, are not supported.
  CBOR_TYPE_SIMPLE = 7,
};

static bool CborWriteWouldOverflowCursor(size_t size, struct CborOut* out) {
  return size > SIZE_MAX - out->cursor;
}

static bool CborWriteFitsInBuffer(size_t size, struct CborOut* out) {
  return out->cursor <= out->buffer_size &&
         size <= out->buffer_size - out->cursor;
}

static void CborWriteType(enum CborType type, uint64_t val,
                          struct CborOut* out) {
  size_t size;
  if (val <= 23) {
    size = 1;
  } else if (val <= 0xff) {
    size = 2;
  } else if (val <= 0xffff) {
    size = 3;
  } else if (val <= 0xffffffff) {
    size = 5;
  } else {
    size = 9;
  }
  if (CborWriteWouldOverflowCursor(size, out)) {
    out->cursor = SIZE_MAX;
    return;
  }
  if (CborWriteFitsInBuffer(size, out)) {
    if (size == 1) {
      out->buffer[out->cursor] = (type << 5) | val;
    } else if (size == 2) {
      out->buffer[out->cursor] = (type << 5) | 24;
      out->buffer[out->cursor + 1] = val & 0xff;
    } else if (size == 3) {
      out->buffer[out->cursor] = (type << 5) | 25;
      out->buffer[out->cursor + 1] = (val >> 8) & 0xff;
      out->buffer[out->cursor + 2] = val & 0xff;
    } else if (size == 5) {
      out->buffer[out->cursor] = (type << 5) | 26;
      out->buffer[out->cursor + 1] = (val >> 24) & 0xff;
      out->buffer[out->cursor + 2] = (val >> 16) & 0xff;
      out->buffer[out->cursor + 3] = (val >> 8) & 0xff;
      out->buffer[out->cursor + 4] = val & 0xff;
    } else if (size == 9) {
      out->buffer[out->cursor] = (type << 5) | 27;
      out->buffer[out->cursor + 1] = (val >> 56) & 0xff;
      out->buffer[out->cursor + 2] = (val >> 48) & 0xff;
      out->buffer[out->cursor + 3] = (val >> 40) & 0xff;
      out->buffer[out->cursor + 4] = (val >> 32) & 0xff;
      out->buffer[out->cursor + 5] = (val >> 24) & 0xff;
      out->buffer[out->cursor + 6] = (val >> 16) & 0xff;
      out->buffer[out->cursor + 7] = (val >> 8) & 0xff;
      out->buffer[out->cursor + 8] = val & 0xff;
    }
  }
  out->cursor += size;
}

static void CborWriteStr(enum CborType type, size_t data_size,
                         const uint8_t* data, struct CborOut* out) {
  CborWriteType(type, data_size, out);
  if (CborWriteWouldOverflowCursor(data_size, out)) {
    out->cursor = SIZE_MAX;
    return;
  }
  if (CborWriteFitsInBuffer(data_size, out) && data_size) {
    memcpy(&out->buffer[out->cursor], data, data_size);
  }
  out->cursor += data_size;
}

void CborWriteInt(int64_t val, struct CborOut* out) {
  if (val < 0) {
    CborWriteType(CBOR_TYPE_NINT, (-1 - val), out);
  } else {
    CborWriteType(CBOR_TYPE_UINT, val, out);
  }
}

void CborWriteBstr(size_t data_size, const uint8_t* data, struct CborOut* out) {
  CborWriteStr(CBOR_TYPE_BSTR, data_size, data, out);
}

void CborWriteTstr(const char* str, struct CborOut* out) {
  CborWriteStr(CBOR_TYPE_TSTR, strlen(str), (const uint8_t*)str, out);
}

void CborWriteArray(size_t num_elements, struct CborOut* out) {
  CborWriteType(CBOR_TYPE_ARRAY, num_elements, out);
}

void CborWriteMap(size_t num_pairs, struct CborOut* out) {
  CborWriteType(CBOR_TYPE_MAP, num_pairs, out);
}

void CborWriteFalse(struct CborOut* out) {
  CborWriteType(CBOR_TYPE_SIMPLE, /*val=*/20, out);
}

void CborWriteTrue(struct CborOut* out) {
  CborWriteType(CBOR_TYPE_SIMPLE, /*val=*/21, out);
}

void CborWriteNull(struct CborOut* out) {
  CborWriteType(CBOR_TYPE_SIMPLE, /*val=*/22, out);
}
