# 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.
"""Connects services to HTTP Load Balancer.

This is normaly to be used with a Back-End service (replicated_service.py).
It essentially allows you to deploy IGM and AS combinations to X number
of zones and places an http load balancer in front of the service.
"""
import common
import default

# Properties for this component
DEFAULT_SERVICE = default.DEFAULT_SERVICE
HOST_RULES = default.HOST_RULES
IP_PROTO = default.IP_PROTO
PATH_MATCHERS = default.PATH_MATCHERS
PORT = default.PORT
SRC_RANGES = default.SRC_RANGES
ADD_FIREWALL = 'addFirewall'
N_OF_IPS = 'numberOfIps'


def GenerateLoadBalancer(context):
  """Generates the urlMap and globalForwardingRule part of the LB."""
  name = context.env['name']
  prop = context.properties

  resource = [
      {
          'name': common.AutoName(name, default.URL_MAP),
          'type': default.URL_MAP,
          'properties': {
              'defaultService': prop[DEFAULT_SERVICE],
              'hostRules': prop[HOST_RULES],
              'pathMatchers': prop[PATH_MATCHERS],
          }
      }, {
          'name': common.AutoName(name, default.PROXY),
          'type': default.PROXY,
          'properties': {
              'urlMap': common.AutoRef(name, default.URL_MAP),
          }
      },
  ]  # pyformat: disable
  return resource


def GenerateGlobalForwardingRule(context, number):
  """Generates a Global Forwarding Rule with the passed name."""
  name = context.env['name']
  prop = context.properties
  protocol = prop[IP_PROTO]
  return {
      'name': common.AutoName(name, default.GF_RULE, str(number)),
      'type': default.GF_RULE,
      'properties': {
          'IPProtocol': protocol,
          'portRange': prop[PORT],
          'target': common.AutoRef(name, default.PROXY),
      }
  }  # pyformat: disable


def GenerateNGlobalForwardingRules(context):
  """Generates one or more ip addresses that points to this Load Balancer."""
  prop = context.properties
  n_of_ips = prop[N_OF_IPS]

  return [GenerateGlobalForwardingRule(context, idx)
          for idx in xrange(0, n_of_ips)]


def GenerateFirewall(context):
  """Generates a firewall if prop[ADD_FIREWALL] is true."""
  name = context.env['name']
  prop = context.properties
  src_ranges = prop[SRC_RANGES]
  add_firewall = prop[ADD_FIREWALL]
  instances = []
  if add_firewall:
    # pyformat: disable
    instances.append({
        'name': common.AutoName(name, default.FIREWALL),
        'type': default.FIREWALL,
        'properties': {
            'sourceRanges': src_ranges,
            'allowed': [{
                'IPProtocol': prop[IP_PROTO],
                'ports': [prop[PORT]],
            }],
        }
    })
  # pyformat: enable
  return instances


def GenerateResourceList(context):
  """Returns list of resources generated by this module."""
  resources = GenerateLoadBalancer(context)
  resources += GenerateNGlobalForwardingRules(context)
  resources += GenerateFirewall(context)
  return resources


@common.FormatErrorsDec
def GenerateConfig(context):
  """Generates YAML resource configuration."""
  return common.MakeResource(GenerateResourceList(context))
