#!/usr/bin/python2.7
# Copyright 2010 Google Inc. All Rights Reserved.
#
#  Licensed 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.

"""Template objects which represent data types.

This module contains objects which usable in templates and represent data type
idioms.
"""

__author__ = 'aiuto@google.com (Tony Aiuto)'

from googleapis.codegen import template_objects


class DataType(template_objects.CodeObject):
  """Template object which represents a data type.

  This is the base class for things which might be data type definitions, such
  as Schema objects derived from JSONSchema blocks or primitive types.
  """

  def __init__(self, def_dict, api, parent=None, language_model=None):
    """Construct a DataType.

    Args:
      def_dict: (dict) The discovery dictionary for this element.
      api: (Api) The Api instance which owns this element.
      parent: (CodeObject) The parent of this element.
      language_model: (LanguageModel) The language we are targetting.
        Dynamically defaults to the parent's language model.
    """
    super(DataType, self).__init__(def_dict, api, parent=parent,
                                   language_model=language_model)
    self._json_type = def_dict.get('type')
    # If the schema has an id, that is a good default class name for it.
    schema_id = def_dict.get('id')
    if schema_id:
      self.SetTemplateValue('className', schema_id)
    # Top level primitive and container classes end up as known schema objects,
    # because some languages will want to generate definitions for them. Thus
    # they need a module. ComplexDataType instances might set a different
    # module in their constructor. The check for the api is to facilitiate
    # unit tests, which sometimes create types without any API.
    # TODO(user): Do not set _module here. Let it be dyanmically found from
    # the parent when needed. But, there is currently a problem with
    # BuildSchemaDefinitions where the top level schemas do not have a parent
    # because we are calling 'self.DataTypeFromJson(def_dict, name)' without
    # the parent parameter. If we add parent there, all hell seems to break.
    # Fix that and remove this.
    if self.api and hasattr(self.api, 'model_module'):
      self._module = self.api.model_module

    # Set some specific annotations as template values.
    annotations = def_dict.get('annotations')
    if annotations:
      required = annotations.get('required')
      self.SetTemplateValue('required_for_methods', required)

  @property
  def json_type(self):
    """Expose the type element from the JSON Schema type definition."""
    return self._json_type

  @property
  def code_type(self):
    """Returns the string representing this datatype."""
    return self.values.get('codeType') or self.values.get('className')

  @property
  def safe_code_type(self):
    """Returns the safe code type representing this datatype."""
    return self.safeClassName or self.code_type

  @property
  def primitive_data_type(self):
    """Returns the language specific primitive representing this datatype."""
    return None

  @property
  def class_name(self):