#!/usr/bin/env python
"""
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you 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

    http://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.

Slider Agent

"""

__all__ = ["Resource", "ResourceArgument", "ForcedListArgument",
           "BooleanArgument"]

from resource_management.core.exceptions import Fail, InvalidArgument
from resource_management.core.environment import Environment
from resource_management.core.logger import Logger

class ResourceArgument(object):
  def __init__(self, default=None, required=False):
    self.required = False # Prevents the initial validate from failing
    if hasattr(default, '__call__'):
      self.default = default
    else:
      self.default = self.validate(default)
    self.required = required

  def validate(self, value):
    if self.required and value is None:
      raise InvalidArgument("Required argument %s missing" % self.name)
    return value


class ForcedListArgument(ResourceArgument):
  def validate(self, value):
    value = super(ForcedListArgument, self).validate(value)
    if not isinstance(value, (tuple, list)):
      value = [value]
    return value


class BooleanArgument(ResourceArgument):
  def validate(self, value):
    value = super(BooleanArgument, self).validate(value)
    if not value in (True, False):
      raise InvalidArgument(
        "Expected a boolean for %s received %r" % (self.name, value))
    return value


class Accessor(object):
  def __init__(self, name):
    self.name = name

  def __get__(self, obj, cls):
    try:
      return obj.arguments[self.name]
    except KeyError:
      val = obj._arguments[self.name].default
      if hasattr(val, '__call__'):
        val = val(obj)
      return val

  def __set__(self, obj, value):
    obj.arguments[self.name] = obj._arguments[self.name].validate(value)


class ResourceMetaclass(type):
  # def __new__(cls, name, bases, attrs):
  #     super_new = super(ResourceMetaclass, cls).__new__
  #     return super_new(cls, name, bases, attrs)

  def __init__(mcs, _name, bases, attrs):
    mcs._arguments = getattr(bases[0], '_arguments', {}).copy()
    for key, value in list(attrs.items()):
      if isinstance(value, ResourceArgument):
        value.name = key
        mcs._arguments[key] = value
        setattr(mcs, key, Accessor(key))
  
  
class Resource(object):
  __metaclass__ = ResourceMetaclass

  action = ForcedListArgument(default="nothing")
  ignore_failures = BooleanArgument(default=False)
  not_if = ResourceArgument() # pass command e.g. not_if = ('ls','/root/jdk')
  only_if = ResourceArgument() # pass command
  initial_wait = ResourceArgument() # in seconds

  actions = ["nothing"]
  
  def __new__(cls, name, env=None, provider=None, **kwargs):
    if isinstance(name, list):
      while len(name) != 1:
        cls(name.pop(0), env, provider, **kwargs)
        
      name = name[0]
    
    env = env or Environment.get_instance()
    provider = provider or getattr(cls, 'provider', None)
    
    r_type = cls.__name__
    if r_type not in env.resources:
      env.resources[r_type] = {}

    obj = super(Resource, cls).__new__(cls)
    env.resources[r_type][name] = obj
    env.resource_list.append(obj)
    return obj

  def __init__(self, name, env=None, provider=None, **kwargs):
    if isinstance(name, list):
      name = name.pop(0)
    
    if hasattr(self, 'name'):
      return

    self.env = env or Environment.get_instance()
    self.name = name
     
    self.provider = provider or getattr(self, 'provider', None)

    self.arguments = {}
    for key, value in kwargs.items():
      try:
        arg = self._arguments[key]
      except KeyError:
        raise Fail("%s received unsupported argument %s" % (self, key))
      else:
        try:
          self.arguments[key] = arg.validate(value)
        except InvalidArgument, exc:
          raise InvalidArgument("%s %s" % (self, exc))
    
    if not self.env.test_mode:
      self.env.run()

  def validate(self):
    pass

  def __repr__(self):
    return "%s['%s']" % (self.__class__.__name__, self.name)

  def __unicode__(self):
    return u"%s['%s']" % (self.__class__.__name__, self.name)

  def __getstate__(self):
    return dict(
      name=self.name,
      provider=self.provider,
      arguments=self.arguments,
      env=self.env,
    )

  def __setstate__(self, state):
    self.name = state['name']
    self.provider = state['provider']
    self.arguments = state['arguments']
    self.env = state['env']

    self.validate()
