/**
 * @file
 * SNMP table support implementation.
 */

/*
 * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
 * OF SUCH DAMAGE.
 *
 * This file is part of the lwIP TCP/IP stack.
 *
 * Author: Martin Hentschel <info@cl-soft.de>
 *
 */

#include "lwip/apps/snmp_opts.h"

#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */

#include "lwip/apps/snmp_core.h"
#include "lwip/apps/snmp_table.h"
#include <string.h>

snmp_err_t snmp_table_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance *instance)
{
  snmp_err_t ret = SNMP_ERR_NOSUCHINSTANCE;
  const struct snmp_table_node *table_node = (const struct snmp_table_node *)(const void *)instance->node;

  LWIP_UNUSED_ARG(root_oid);
  LWIP_UNUSED_ARG(root_oid_len);

  /* check min. length (fixed row entry definition, column, row instance oid with at least one entry */
  /* fixed row entry always has oid 1 */
  if ((instance->instance_oid.len >= 3) && (instance->instance_oid.id[0] == 1)) {
    /* search column */
    const struct snmp_table_col_def *col_def = table_node->columns;
    u16_t i = table_node->column_count;
    while (i > 0) {
      if (col_def->index == instance->instance_oid.id[1]) {
        break;
      }

      col_def++;
      i--;
    }

    if (i > 0) {
      /* everything may be overwritten by get_cell_instance_method() in order to implement special handling for single columns/cells */
      instance->asn1_type = col_def->asn1_type;
      instance->access    = col_def->access;
      instance->get_value = table_node->get_value;
      instance->set_test  = table_node->set_test;
      instance->set_value = table_node->set_value;

      ret = table_node->get_cell_instance(
              &(instance->instance_oid.id[1]),
              &(instance->instance_oid.id[2]),
              instance->instance_oid.len - 2,
              instance);
    }
  }

  return ret;
}

snmp_err_t snmp_table_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance *instance)
{
  const struct snmp_table_node *table_node = (const struct snmp_table_node *)(const void *)instance->node;
  const struct snmp_table_col_def *col_def;
  struct snmp_obj_id row_oid;
  u32_t column = 0;
  snmp_err_t result;

  LWIP_UNUSED_ARG(root_oid);
  LWIP_UNUSED_ARG(root_oid_len);

  /* check that first part of id is 0 or 1, referencing fixed row entry */
  if ((instance->instance_oid.len > 0) && (instance->instance_oid.id[0] > 1)) {
    return SNMP_ERR_NOSUCHINSTANCE;
  }
  if (instance->instance_oid.len > 1) {
    column = instance->instance_oid.id[1];
  }
  if (instance->instance_oid.len > 2) {
    snmp_oid_assign(&row_oid, &(instance->instance_oid.id[2]), instance->instance_oid.len - 2);
  } else {
    row_oid.len = 0;
  }

  instance->get_value    = table_node->get_value;
  instance->set_test     = table_node->set_test;
  instance->set_value    = table_node->set_value;

  /* resolve column and value */
  do {
    u16_t i;
    const struct snmp_table_col_def *next_col_def = NULL;
    col_def = table_node->columns;

    for (i = 0; i < table_node->column_count; i++) {
      if (col_def->index == column) {
        next_col_def = col_def;
        break;
      } else if ((col_def->index > column) && ((next_col_def == NULL) || (col_def->index < next_col_def->index))) {
        next_col_def = col_def;
      }
      col_def++;
    }

    if (next_col_def == NULL) {
      /* no further column found */
      return SNMP_ERR_NOSUCHINSTANCE;
    }

    instance->asn1_type          = next_col_def->asn1_type;
    instance->access             = next_col_def->access;

    result = table_node->get_next_cell_instance(
               &next_col_def->index,
               &row_oid,
               instance);

    if (result == SNMP_ERR_NOERROR) {
      col_def = next_col_def;
      break;
    }

    row_oid.len = 0; /* reset row_oid because we switch to next column and start with the first entry there */
    column = next_col_def->index + 1;
  } while (1);

  /* build resulting oid */
  instance->instance_oid.len   = 2;
  instance->instance_oid.id[0] = 1;
  instance->instance_oid.id[1] = col_def->index;
  snmp_oid_append(&instance->instance_oid, row_oid.id, row_oid.len);

  return SNMP_ERR_NOERROR;
}


snmp_err_t snmp_table_simple_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance *instance)
{
  snmp_err_t ret = SNMP_ERR_NOSUCHINSTANCE;
  const struct snmp_table_simple_node *table_node = (const struct snmp_table_simple_node *)(const void *)instance->node;

  LWIP_UNUSED_ARG(root_oid);
  LWIP_UNUSED_ARG(root_oid_len);

  /* check min. length (fixed row entry definition, column, row instance oid with at least one entry */
  /* fixed row entry always has oid 1 */
  if ((instance->instance_oid.len >= 3) && (instance->instance_oid.id[0] == 1)) {
    ret = table_node->get_cell_value(
            &(instance->instance_oid.id[1]),
            &(instance->instance_oid.id[2]),
            instance->instance_oid.len - 2,
            &instance->reference,
            &instance->reference_len);

    if (ret == SNMP_ERR_NOERROR) {
      /* search column */
      const struct snmp_table_simple_col_def *col_def = table_node->columns;
      u32_t i = table_node->column_count;
      while (i > 0) {
        if (col_def->index == instance->instance_oid.id[1]) {
          break;
        }

        col_def++;
        i--;
      }

      if (i > 0) {
        instance->asn1_type = col_def->asn1_type;
        instance->access    = SNMP_NODE_INSTANCE_READ_ONLY;
        instance->set_test  = NULL;
        instance->set_value = NULL;

        switch (col_def->data_type) {
          case SNMP_VARIANT_VALUE_TYPE_U32:
            instance->get_value = snmp_table_extract_value_from_u32ref;
            break;
          case SNMP_VARIANT_VALUE_TYPE_S32:
            instance->get_value = snmp_table_extract_value_from_s32ref;
            break;
          case SNMP_VARIANT_VALUE_TYPE_PTR: /* fall through */
          case SNMP_VARIANT_VALUE_TYPE_CONST_PTR:
            instance->get_value = snmp_table_extract_value_from_refconstptr;
            break;
          default:
            LWIP_DEBUGF(SNMP_DEBUG, ("snmp_table_simple_get_instance(): unknown column data_type: %d\n", col_def->data_type));
            return SNMP_ERR_GENERROR;
        }

        ret = SNMP_ERR_NOERROR;
      } else {
        ret = SNMP_ERR_NOSUCHINSTANCE;
      }
    }
  }

  return ret;
}

snmp_err_t snmp_table_simple_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance *instance)
{
  const struct snmp_table_simple_node *table_node = (const struct snmp_table_simple_node *)(const void *)instance->node;
  const struct snmp_table_simple_col_def *col_def;
  struct snmp_obj_id row_oid;
  u32_t column = 0;
  snmp_err_t result;

  LWIP_UNUSED_ARG(root_oid);
  LWIP_UNUSED_ARG(root_oid_len);

  /* check that first part of id is 0 or 1, referencing fixed row entry */
  if ((instance->instance_oid.len > 0) && (instance->instance_oid.id[0] > 1)) {
    return SNMP_ERR_NOSUCHINSTANCE;
  }
  if (instance->instance_oid.len > 1) {
    column = instance->instance_oid.id[1];
  }
  if (instance->instance_oid.len > 2) {
    snmp_oid_assign(&row_oid, &(instance->instance_oid.id[2]), instance->instance_oid.len - 2);
  } else {
    row_oid.len = 0;
  }

  /* resolve column and value */
  do {
    u32_t i;
    const struct snmp_table_simple_col_def *next_col_def = NULL;
    col_def = table_node->columns;

    for (i = 0; i < table_node->column_count; i++) {
      if (col_def->index == column) {
        next_col_def = col_def;
        break;
      } else if ((col_def->index > column) && ((next_col_def == NULL) ||
                 (col_def->index < next_col_def->index))) {
        next_col_def = col_def;
      }
      col_def++;
    }

    if (next_col_def == NULL) {
      /* no further column found */
      return SNMP_ERR_NOSUCHINSTANCE;
    }

    result = table_node->get_next_cell_instance_and_value(
               &next_col_def->index,
               &row_oid,
               &instance->reference,
               &instance->reference_len);

    if (result == SNMP_ERR_NOERROR) {
      col_def = next_col_def;
      break;
    }

    row_oid.len = 0; /* reset row_oid because we switch to next column and start with the first entry there */
    column = next_col_def->index + 1;
  } while (1);

  instance->asn1_type = col_def->asn1_type;
  instance->access    = SNMP_NODE_INSTANCE_READ_ONLY;
  instance->set_test  = NULL;
  instance->set_value = NULL;

  switch (col_def->data_type) {
    case SNMP_VARIANT_VALUE_TYPE_U32:
      instance->get_value = snmp_table_extract_value_from_u32ref;
      break;
    case SNMP_VARIANT_VALUE_TYPE_S32:
      instance->get_value = snmp_table_extract_value_from_s32ref;
      break;
    case SNMP_VARIANT_VALUE_TYPE_PTR: /* fall through */
    case SNMP_VARIANT_VALUE_TYPE_CONST_PTR:
      instance->get_value = snmp_table_extract_value_from_refconstptr;
      break;
    default:
      LWIP_DEBUGF(SNMP_DEBUG, ("snmp_table_simple_get_instance(): unknown column data_type: %d\n", col_def->data_type));
      return SNMP_ERR_GENERROR;
  }

  /* build resulting oid */
  instance->instance_oid.len   = 2;
  instance->instance_oid.id[0] = 1;
  instance->instance_oid.id[1] = col_def->index;
  snmp_oid_append(&instance->instance_oid, row_oid.id, row_oid.len);

  return SNMP_ERR_NOERROR;
}


s16_t
snmp_table_extract_value_from_s32ref(struct snmp_node_instance *instance, void *value)
{
  s32_t *dst = (s32_t *)value;
  *dst = instance->reference.s32;
  return sizeof(*dst);
}

s16_t
snmp_table_extract_value_from_u32ref(struct snmp_node_instance *instance, void *value)
{
  u32_t *dst = (u32_t *)value;
  *dst = instance->reference.u32;
  return sizeof(*dst);
}

s16_t
snmp_table_extract_value_from_refconstptr(struct snmp_node_instance *instance, void *value)
{
  MEMCPY(value, instance->reference.const_ptr, instance->reference_len);
  return (u16_t)instance->reference_len;
}

#endif /* LWIP_SNMP */
