/****************************************************************************/
/* Copyright (c) 2000 MBARI                                                 */
/* MBARI Proprietary Information. All rights reserved.                      */
/****************************************************************************/
/* Summary  :                                                               */
/* Filename : Attributes.cc                                                 */
/* Author   :                                                               */
/* Project  :                                                               */
/* Version  : 1.0                                                           */
/* Created  : 02/07/2000                                                    */
/* Modified :                                                               */
/* Archived :                                                               */
/****************************************************************************/
/* Modification History:                                                    */
/****************************************************************************/
#include <string.h>
#include <malloc.h>
#include "Attributes.h"
#include "Syslog.h"


Attributes::Attributes(const char *objectName)
{
  _objectName = strdup(objectName);
}


Attributes::~Attributes()
{
  free((void *)_objectName);
  for (int i = 0; i < list.size(); i++) {
    Attribute *attribute;
    list.get(i, &attribute);
    delete attribute;
  }
}


int Attributes::parse(Attribute::Input *input)
{
  Boolean debug = False;
  Boolean found = False;
  char errorBuf[256];

  dprintf("Attributes::parse() - size=%d\n", list.size());

  for (int j = 0; j < list.size(); j++) {

    Attribute *attribute;
    list.get(j, &attribute);

    dprintf("Attributes::parse() "
	    "- compare attribute name %s to input name %s\n", 
	    attribute->name(), input->name);

    if (!strcmp(input->name, attribute->name())) {
      found = True;

      try {
	attribute->setValue(input->valueString);
	attribute->markAsSet();
	dprintf("Attributes::parse() -- Found value for %s", 
		attribute->name() );
	dprintf("Attributes::parse() -- %s is %s",
		attribute->name(),
		attribute->valueHasBeenSet() ? "set" : "not set" );
      }
      catch (...) {
	// Conversion error?
	sprintf(errorBuf, "Caught conversion error for value \"%s\"\n", 
		input->valueString);

	Syslog::write("%s\n", errorBuf);

	return -1;
      }

      break;
    }
  }
  if (!found) {
    // Invalid input attribute name
    sprintf(errorBuf, "Unknown attribute name: \"%s\"\n", input->name);
    Syslog::write("%s\n", errorBuf);
    return -1;
  }

  return 0;
}


int Attributes::parse(AttributeInputList *inputs)
{
  Boolean debug = False;
  Boolean error = False;
  Attribute::Input *input;
  Attribute *attribute;

  int i;

  // Parse each input
  for (i = 0; i < inputs->size(); i++) {

    inputs->get(i, &input);

    if (parse(input) == -1)
      error = True;
  }

  if (error)
    return -1;
  else
    return 0;
}


int Attributes::verify()
{
  Boolean debug = False;
  Boolean error = False;

  Attribute *attribute;

  // Check that all mandatory attributes have been specified
  for (int i = 0; i < list.size(); i++) {
    list.get(i, &attribute);

    dprintf("Attribute %s is hasDefault = %s, isSet = %s",
	    attribute->name(),
	    attribute->hasDefault() ? "true" : "false",
	    attribute->valueHasBeenSet() ? "true" : "false" );

    if( attribute->verify() == False ) {
	 Syslog::write("Attribute \"%s\" failed to verify itself",
		       attribute->name() );
    }

    if (!attribute->hasDefault() && !attribute->valueHasBeenSet()) {

      Syslog::write("Mandatory attribute \"%s\" not specified "
		      "for object \"%s\"\n", 
		      attribute->name(), _objectName); 

      error = True;
    }
  }

  dprintf("Attributes::verify() -- Attribute set %s is %s",
	  _objectName,
	  (error) ? "not done" : "done");

  if (error)
    return -1;
  else
    return 0;
}


void Attributes::printDescriptions()
{

  Syslog::write("Valid attribute descriptions:");

  Attribute *attribute;

  // Print description of each attribute
  for (int i = 0; i < list.size(); i++) {
    list.get(i, &attribute);
    attribute->printDescription();
    Syslog::write(" ");
  }
}


const char *Attributes::objectName()
{
  return _objectName;
}
