// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <mojo/bindings/struct.h>

#include <assert.h>
#include <mojo/bindings/internal/type_descriptor.h>
#include <mojo/bindings/union.h>
#include <string.h>

size_t MojomStruct_ComputeSerializedSize(
    const struct MojomTypeDescriptorStruct* in_type_desc,
    const struct MojomStructHeader* in_struct) {
  assert(in_struct);
  assert(in_type_desc);

  size_t size = in_struct->num_bytes;
  for (size_t i = 0; i < in_type_desc->num_entries; i++) {
    const struct MojomTypeDescriptorStructEntry* entry =
        &(in_type_desc->entries[i]);

    if (!MojomType_IsPointer(entry->elem_type) &&
        entry->elem_type != MOJOM_TYPE_DESCRIPTOR_TYPE_UNION)
      continue;

    if (in_struct->version < entry->min_version)
      continue;

    size += MojomType_DispatchComputeSerializedSize(
        entry->elem_type, entry->elem_descriptor, entry->nullable,
        (char*)in_struct + sizeof(struct MojomStructHeader) + entry->offset);
  }
  return size;
}

void MojomStruct_EncodePointersAndHandles(
    const struct MojomTypeDescriptorStruct* in_type_desc,
    struct MojomStructHeader* inout_struct,
    uint32_t in_struct_size,
    struct MojomHandleBuffer* inout_handles_buffer) {
  assert(in_type_desc);
  assert(inout_struct);
  assert(in_struct_size >= sizeof(struct MojomStructHeader));

  for (size_t i = 0; i < in_type_desc->num_entries; i++) {
    const struct MojomTypeDescriptorStructEntry* entry =
        &(in_type_desc->entries[i]);

    if (inout_struct->version < entry->min_version)
      continue;

    assert(sizeof(struct MojomStructHeader) + entry->offset < in_struct_size);
    void* elem_data = ((char*)inout_struct + sizeof(struct MojomStructHeader) +
                       entry->offset);

    MojomType_DispatchEncodePointersAndHandles(
        entry->elem_type,
        entry->elem_descriptor,
        entry->nullable,
        elem_data,
        in_struct_size - ((char*)elem_data - (char*)inout_struct),
        inout_handles_buffer);
  }
}

void MojomStruct_DecodePointersAndHandles(
    const struct MojomTypeDescriptorStruct* in_type_desc,
    struct MojomStructHeader* inout_struct,
    uint32_t in_struct_size,
    MojoHandle* inout_handles,
    uint32_t in_num_handles) {
  assert(in_type_desc);
  assert(inout_struct);
  assert(inout_handles != NULL || in_num_handles == 0);

  for (size_t i = 0; i < in_type_desc->num_entries; i++) {
    const struct MojomTypeDescriptorStructEntry* entry =
        &(in_type_desc->entries[i]);

    if (inout_struct->version < entry->min_version)
      continue;

    assert(sizeof(struct MojomStructHeader) + entry->offset < in_struct_size);
    void* elem_data = ((char*)inout_struct + sizeof(struct MojomStructHeader) +
                       entry->offset);

    MojomType_DispatchDecodePointersAndHandles(
        entry->elem_type,
        entry->elem_descriptor,
        entry->nullable,
        elem_data,
        in_struct_size - ((char*)elem_data - (char*)inout_struct),
        inout_handles,
        in_num_handles);
  }
}

static bool is_valid_size_for_version(
    const struct MojomStructHeader* in_struct,
    const struct MojomTypeDescriptorStructVersion versions[],
    uint32_t num_versions) {
  // Scan for a version size in reverse order (assuming structs are often newer
  // versions than old). Seek to the most recent version that |in_struct| is
  // compatible with.
  uint32_t i = num_versions - 1;
  for (; i > 0 && versions[i].version > in_struct->version; i--);

  if (in_struct->version == versions[i].version) {
    return in_struct->num_bytes == versions[i].num_bytes;
  } else {
    return in_struct->num_bytes >= versions[i].num_bytes;
  }
}

MojomValidationResult MojomStruct_Validate(
    const struct MojomTypeDescriptorStruct* in_type_desc,
    const struct MojomStructHeader* in_struct,
    uint32_t in_struct_size,
    uint32_t in_num_handles,
    struct MojomValidationContext* inout_context) {
  assert(in_type_desc);
  assert(in_struct);

  // Struct header validation.
  if (in_struct_size < sizeof(struct MojomStructHeader))
    return MOJOM_VALIDATION_ILLEGAL_MEMORY_RANGE;

  if (in_struct->num_bytes > in_struct_size)
    return MOJOM_VALIDATION_ILLEGAL_MEMORY_RANGE;

  if (!is_valid_size_for_version(in_struct, in_type_desc->versions,
                                 in_type_desc->num_versions)) {
    return MOJOM_VALIDATION_UNEXPECTED_STRUCT_HEADER;
  }

  if ((in_struct->num_bytes & 7) != 0)
    return MOJOM_VALIDATION_MISALIGNED_OBJECT;

  // From here on out, all pointers need to point past the end of this struct.
  inout_context->next_pointer = (char*)in_struct + in_struct->num_bytes;

  for (size_t i = 0; i < in_type_desc->num_entries; i++) {
    const struct MojomTypeDescriptorStructEntry* entry =
        &(in_type_desc->entries[i]);

    if (in_struct->version < entry->min_version)
        continue;

    void* elem_data = ((char*)in_struct + sizeof(struct MojomStructHeader) +
                       entry->offset);
    MojomValidationResult result = MojomType_DispatchValidate(
        entry->elem_type,
        entry->elem_descriptor,
        entry->nullable,
        elem_data,
        in_struct_size - ((char*)elem_data - (char*)in_struct),
        in_num_handles,
        inout_context);
    if (result != MOJOM_VALIDATION_ERROR_NONE)
      return result;
  }

  return MOJOM_VALIDATION_ERROR_NONE;
}

bool MojomStruct_DeepCopy(
    struct MojomBuffer* buffer,
    const struct MojomTypeDescriptorStruct* in_type_desc,
    const struct MojomStructHeader* in_struct,
    struct MojomStructHeader** out_struct) {
  assert(in_type_desc);
  assert(in_struct);
  assert(out_struct);

  *out_struct = MojomBuffer_Allocate(buffer, in_struct->num_bytes);
  if (*out_struct == NULL)
    return false;

  memcpy(*out_struct, in_struct, in_struct->num_bytes);

  for (size_t i = 0; i < in_type_desc->num_entries; i++) {
    const struct MojomTypeDescriptorStructEntry* entry =
        &(in_type_desc->entries[i]);

    if (in_struct->version < entry->min_version)
        continue;

    void* in_elem_data =
        ((char*)in_struct + sizeof(struct MojomStructHeader) + entry->offset);
    void* out_elem_data = ((char*)*out_struct +
                           sizeof(struct MojomStructHeader) + entry->offset);
    if (!MojomType_DispatchDeepCopy(
        buffer,
        entry->elem_type,
        entry->elem_descriptor,
        in_elem_data,
        out_elem_data)) {
      return false;
    }
  }

  return true;
}
