# -*- coding: utf-8 -*-
# Copyright 2011 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Module to represent a Field in an experiment file."""


class Field(object):
  """Class representing a Field in an experiment file."""

  def __init__(self, name, required, default, inheritable, description):
    self.name = name
    self.required = required
    self.assigned = False
    self.default = default
    self._value = default
    self.inheritable = inheritable
    self.description = description

  def Set(self, value, parse=True):
    if parse:
      self._value = self._Parse(value)
    else:
      self._value = value
    self.assigned = True

  def Append(self, value):
    self._value += self._Parse(value)
    self.assigned = True

  def _Parse(self, value):
    return value

  def Get(self):
    return self._value

  def GetString(self):
    return str(self._value)


class TextField(Field):
  """Class of text field."""

  def __init__(self,
               name,
               required=False,
               default='',
               inheritable=False,
               description=''):
    super(TextField, self).__init__(name, required, default, inheritable,
                                    description)

  def _Parse(self, value):
    return str(value)


class BooleanField(Field):
  """Class of boolean field."""

  def __init__(self,
               name,
               required=False,
               default=False,
               inheritable=False,
               description=''):
    super(BooleanField, self).__init__(name, required, default, inheritable,
                                       description)

  def _Parse(self, value):
    if value.lower() == 'true':
      return True
    elif value.lower() == 'false':
      return False
    raise TypeError(
        "Invalid value for '%s'. Must be true or false." % self.name)


class IntegerField(Field):
  """Class of integer field."""

  def __init__(self,
               name,
               required=False,
               default=0,
               inheritable=False,
               description=''):
    super(IntegerField, self).__init__(name, required, default, inheritable,
                                       description)

  def _Parse(self, value):
    return int(value)


class FloatField(Field):
  """Class of float field."""

  def __init__(self,
               name,
               required=False,
               default=0,
               inheritable=False,
               description=''):
    super(FloatField, self).__init__(name, required, default, inheritable,
                                     description)

  def _Parse(self, value):
    return float(value)


class ListField(Field):
  """Class of list field."""

  def __init__(self,
               name,
               required=False,
               default=None,
               inheritable=False,
               description=''):
    super(ListField, self).__init__(name, required, default, inheritable,
                                    description)

  def _Parse(self, value):
    return value.split()

  def GetString(self):
    return ' '.join(self._value)

  def Append(self, value):
    v = self._Parse(value)
    if not self._value:
      self._value = v
    else:
      self._value += v
    self.assigned = True


class EnumField(Field):
  """Class of enum field."""

  def __init__(self,
               name,
               options,
               required=False,
               default='',
               inheritable=False,
               description=''):
    super(EnumField, self).__init__(name, required, default, inheritable,
                                    description)
    self.options = options

  def _Parse(self, value):
    if value not in self.options:
      raise TypeError("Invalid enum value for field '%s'. Must be one of (%s)" %
                      (self.name, ', '.join(self.options)))
    return str(value)
