# Copyright 2015 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.
"""Generic simple functions used for python based templage generation."""

import re
import sys
import traceback
import default

import yaml

RFC1035_RE = re.compile(r'^[a-z][-a-z0-9]{1,61}[a-z0-9]{1}$')


class Error(Exception):
  """Common exception wrapper for template exceptions."""
  pass


def AddDiskResourcesIfNeeded(context):
  """Checks context if disk resources need to be added."""
  if default.DISK_RESOURCES in context.properties:
    return context.properties[default.DISK_RESOURCES]
  else:
    return []


def AutoName(base, resource, *args):
  """Helper method to generate names automatically based on default."""
  auto_name = '%s-%s' % (base, '-'.join(list(args) + [default.AKA[resource]]))
  if not RFC1035_RE.match(auto_name):
    raise Error('"%s" name for type %s does not match RFC1035 regex (%s)' %
                (auto_name, resource, RFC1035_RE.pattern))
  return auto_name


def AutoRef(base, resource, *args):
  """Helper method that builds a reference for an auto-named resource."""
  return Ref(AutoName(base, resource, *args))


def OrderedItems(dict_obj):
  """Convenient method to yield sorted iteritems of a dictionary."""
  keys = list(dict_obj.keys())
  keys.sort()
  for k in keys:
    yield (k, dict_obj[k])


def ShortenZoneName(zone):
  """Given a string that looks like a zone name, creates a shorter version."""
  geo, coord, number, letter = re.findall(r'(\w+)-(\w+)(\d)-(\w)', zone)[0]
  geo = geo.lower() if len(geo) == 2 else default.LOC[geo.lower()]
  coord = default.LOC[coord.lower()]
  number = str(number)
  letter = letter.lower()
  return geo + '-' + coord + number + letter


def ZoneToRegion(zone):
  """Derives the region from a zone name."""
  parts = zone.split('-')
  if len(parts) != 3:
    raise Error('Cannot derive region from zone "%s"' % zone)
  return '-'.join(parts[:2])


def FormatException(message):
  """Adds more information to the exception."""
  message = ('Exception Type: %s\n'
             'Details: %s\n'
             'Message: %s\n') % (sys.exc_info()[0], traceback.format_exc(), message)
  return message


def Ref(name):
  return '$(ref.%s.selfLink)' % name


def RefGroup(name):
  return '$(ref.%s.instanceGroup)' % name


def GlobalComputeLink(project, collection, name):
  return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/global/',
                  collection, '/', name])


def LocalComputeLink(project, zone, key, value):
  return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/zones/',