// 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_reader.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,
  CBOR_TYPE_TAG_NOT_SUPPORTED = 6,
  CBOR_TYPE_SIMPLE = 7,
};

static bool CborReadWouldOverflow(size_t size, struct CborIn* in) {
  return size > SIZE_MAX - in->cursor || in->cursor + size > in->buffer_size;
}

static enum CborReadResult CborPeekIntialValueAndArgument(struct CborIn* in,
                                                          uint8_t* size,
                                                          enum CborType* type,
                                                          uint64_t* val) {
  uint8_t initial_byte;
  uint8_t additional_information;
  uint64_t value;
  uint8_t bytes = 1;
  if (CborInAtEnd(in)) {
    return CBOR_READ_RESULT_END;
  }
  initial_byte = in->buffer[in->cursor];
  *type = initial_byte >> 5;
  additional_information = initial_byte & 0x1f;
  if (additional_information <= 23) {
    value = additional_information;
  } else if (additional_information <= 27) {
    bytes += 1 << (additional_information - 24);
    if (CborReadWouldOverflow(bytes, in)) {
      return CBOR_READ_RESULT_END;
    }
    value = 0;
    if (bytes == 2) {
      value |= in->buffer[in->cursor + 1];
    } else if (bytes == 3) {
      value |= (uint16_t)in->buffer[in->cursor + 1] << 8;
      value |= (uint16_t)in->buffer[in->cursor + 2];
    } else if (bytes == 5) {
      value |= (uint32_t)in->buffer[in->cursor + 1] << 24;
      value |= (uint32_t)in->buffer[in->cursor + 2] << 16;
      value |= (uint32_t)in->buffer[in->cursor + 3] << 8;
      value |= (uint32_t)in->buffer[in->cursor + 4];
    } else if (bytes == 9) {
      value |= (uint64_t)in->buffer[in->cursor + 1] << 56;
      value |= (uint64_t)in->buffer[in->cursor + 2] << 48;
      value |= (uint64_t)in->buffer[in->cursor + 3] << 40;
      value |= (uint64_t)in->buffer[in->cursor + 4] << 32;
      value |= (uint64_t)in->buffer[in->cursor + 5] << 24;
      value |= (uint64_t)in->buffer[in->cursor + 6] << 16;
      value |= (uint64_t)in->buffer[in->cursor + 7] << 8;
      value |= (uint64_t)in->buffer[in->cursor + 8];
    }
  } else {
    // Indefinite lengths and reserved values are not supported.
    return CBOR_READ_RESULT_MALFORMED;
  }
  *val = value;
  *size = bytes;
  return CBOR_READ_RESULT_OK;
}

static enum CborReadResult CborReadSize(struct CborIn* in, enum CborType type,
                                        size_t* size) {
  uint8_t bytes;
  enum CborType in_type;
  uint64_t raw;
  enum CborReadResult res =
      CborPeekIntialValueAndArgument(in, &bytes, &in_type, &raw);
  if (res != CBOR_READ_RESULT_OK) {
    return res;
  }
  if (in_type != type) {
    return CBOR_READ_RESULT_NOT_FOUND;
  }
  if (raw > SIZE_MAX) {
    return CBOR_READ_RESULT_MALFORMED;
  }
  *size = raw;
  in->cursor += bytes;
  return CBOR_READ_RESULT_OK;
}

static enum CborReadResult CborReadStr(struct CborIn* in, enum CborType type,
                                       size_t* data_size,
                                       const uint8_t** data) {
  size_t size;
  struct CborIn peeker = *in;
  enum CborReadResult res = CborReadSize(&peeker, type, &size);
  if (res != CBOR_READ_RESULT_OK) {
    return res;
  }
  if (CborReadWouldOverflow(size, &peeker)) {
    return CBOR_READ_RESULT_END;
  }
  *data_size = size;
  *data = &in->buffer[peeker.cursor];
  in->cursor = peeker.cursor + size;
  return CBOR_READ_RESULT_OK;
}

static enum CborReadResult CborReadSimple(struct CborIn* in, uint8_t val) {
  uint8_t bytes;
  enum CborType type;
  uint64_t raw;
  enum CborReadResult res =
      CborPeekIntialValueAndArgument(in, &bytes, &type, &raw);
  if (res != CBOR_READ_RESULT_OK) {
    return res;
  }
  if (type != CBOR_TYPE_SIMPLE || raw != val) {
    return CBOR_READ_RESULT_NOT_FOUND;
  }
  in->cursor += bytes;
  return CBOR_READ_RESULT_OK;
}

enum CborReadResult CborReadInt(struct CborIn* in, int64_t* val) {
  uint8_t bytes;
  enum CborType type;
  uint64_t raw;
  enum CborReadResult res =
      CborPeekIntialValueAndArgument(in, &bytes, &type, &raw);
  if (res != CBOR_READ_RESULT_OK) {
    return res;
  }
  if (type != CBOR_TYPE_UINT && type != CBOR_TYPE_NINT) {
    return CBOR_READ_RESULT_NOT_FOUND;
  }
  if (raw > INT64_MAX) {
    return CBOR_READ_RESULT_MALFORMED;
  }
  *val = (type == CBOR_TYPE_NINT) ? (-1 - (int64_t)raw) : (int64_t)raw;
  in->cursor += bytes;
  return CBOR_READ_RESULT_OK;
}

enum CborReadResult CborReadUint(struct CborIn* in, uint64_t* val) {
  uint8_t bytes;
  enum CborType type;
  enum CborReadResult res =
      CborPeekIntialValueAndArgument(in, &bytes, &type, val);
  if (res != CBOR_READ_RESULT_OK) {
    return res;
  }
  if (type != CBOR_TYPE_UINT) {
    return CBOR_READ_RESULT_NOT_FOUND;
  }
  in->cursor += bytes;
  return CBOR_READ_RESULT_OK;
}

enum CborReadResult CborReadBstr(struct CborIn* in, size_t* data_size,
                                 const uint8_t** data) {
  return CborReadStr(in, CBOR_TYPE_BSTR, data_size, data);
}

enum CborReadResult CborReadTstr(struct CborIn* in, size_t* size,
                                 const char** str) {
  return CborReadStr(in, CBOR_TYPE_TSTR, size, (const uint8_t**)str);
}

enum CborReadResult CborReadArray(struct CborIn* in, size_t* num_elements) {
  return CborReadSize(in, CBOR_TYPE_ARRAY, num_elements);
}

enum CborReadResult CborReadMap(struct CborIn* in, size_t* num_pairs) {
  return CborReadSize(in, CBOR_TYPE_MAP, num_pairs);
}

enum CborReadResult CborReadFalse(struct CborIn* in) {
  return CborReadSimple(in, /*val=*/20);
}

enum CborReadResult CborReadTrue(struct CborIn* in) {
  return CborReadSimple(in, /*val=*/21);
}

enum CborReadResult CborReadNull(struct CborIn* in) {
  return CborReadSimple(in, /*val=*/22);
}

enum CborReadResult CborReadSkip(struct CborIn* in) {
  struct CborIn peeker = *in;
  size_t size_stack[CBOR_READ_SKIP_STACK_SIZE];
  size_t stack_size = 0;

  size_stack[stack_size++] = 1;

  while (stack_size > 0) {
    // Get the type
    uint8_t bytes;
    enum CborType type;
    uint64_t val;
    enum CborReadResult res;

    res = CborPeekIntialValueAndArgument(&peeker, &bytes, &type, &val);
    if (res != CBOR_READ_RESULT_OK) {
      return res;
    }

    if (CborReadWouldOverflow(bytes, &peeker)) {
      return CBOR_READ_RESULT_END;
    }
    peeker.cursor += bytes;

    if (--size_stack[stack_size - 1] == 0) {
      --stack_size;
    }

    switch (type) {
      case CBOR_TYPE_UINT:
      case CBOR_TYPE_NINT:
      case CBOR_TYPE_SIMPLE:
        continue;
      case CBOR_TYPE_BSTR:
      case CBOR_TYPE_TSTR:
        if (CborReadWouldOverflow(val, &peeker)) {
          return CBOR_READ_RESULT_END;
        }
        peeker.cursor += val;
        continue;
      case CBOR_TYPE_MAP:
        if (val > UINT64_MAX / 2) {
          return CBOR_READ_RESULT_END;
        }
        val *= 2;
        break;
      case CBOR_TYPE_ARRAY:
        break;
      default:
        return CBOR_READ_RESULT_MALFORMED;
    }

    // Push a new level of nesting to the stack.
    if (val == 0) {
      continue;
    }
    if (stack_size == CBOR_READ_SKIP_STACK_SIZE) {
      return CBOR_READ_RESULT_MALFORMED;
    }
    size_stack[stack_size++] = val;
  }

  in->cursor = peeker.cursor;
  return CBOR_READ_RESULT_OK;
}
