#  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.

Namespaces:
    =: io.murano
    res: io.murano.resources
    sys: io.murano.system

Name: Environment

Properties:
  name:
    Contract: $.string().notNull()

  applications:
    Contract: [$.class(Application).owned().notNull()]

  agentListener:
    Contract: $.class(sys:AgentListener)
    Usage: Runtime

  stack:
    Contract: $.class(sys:HeatStack)
    Usage: Runtime

  instanceNotifier:
    Contract: $.class(sys:InstanceNotifier)
    Usage: Runtime

  defaultNetworks:
    Contract:
      environment: $.class(res:Network)
      flat: $.class(res:Network)
    Usage: In

  securityGroupManager:
    Contract: $.class(sys:SecurityGroupManager)
    Usage: Runtime

  reporter:
    Contract: $.class(sys:StatusReporter)
    Usage: Runtime

  regionConfigs:
    Contract:
      $.string():
        agentRabbitMq:
          host: $.string().notNull()
          port: $.int() or 5672
          login: $.string().notNull()
          password: $.string().notNull()
          virtual_host: $.string() or '/'
          ssl: $.bool() or false
          ca_certs: $.string() or ''
    Usage: Config

  region:
    Contract: $.string()
    Usage: InOut


Methods:
  initialize:
    Body:
      - $._assignRegions()
      - $generatedEnvironmentName: $.getAttr(generatedEnvironmentName)
      - If: $generatedEnvironmentName = null
        Then:
          - $generatedEnvironmentName: randomName()
          - $.setAttr(generatedEnvironmentName, $generatedEnvironmentName)
      - $this.agentListener: new(sys:AgentListener, name => $generatedEnvironmentName)
      - $stackDescriptionFormat: 'This stack was generated by Murano for environment {0} (ID: {1})'
      - $this.stack: new(sys:HeatStack, $this,
          name => 'murano-' + $generatedEnvironmentName,
          description => $stackDescriptionFormat.format($.name, $.id()))
      - $this.instanceNotifier: new(sys:InstanceNotifier, environment => $this)
      - $this.reporter: new(sys:StatusReporter, environment => $this)
      - $net: null
      - If: $.defaultNetworks.environment != null
        Then:
          - $net: $.defaultNetworks.environment
      - If: $.defaultNetworks.flat != null
        Then:
          - $net: $.defaultNetworks.flat
      - If: $net != null
        Then:
          - $this.securityGroupManager: $net.generateSecurityGroupManager($this)

  deploy:
    Usage: Action
    Body:
      - $.applications.pselect($.deploy())

  destroy:
    Body:
      - $.stack.delete()

  _assignRegions:
    Body:
      - $homeRegion: config(home_region)
      - If: $.region = null
        Then:
          $.region: $homeRegion

      - $defaultRegionConfig:
          agentRabbitMq:
            host: config(rabbitmq, host)
            port: config(rabbitmq, port)
            login: config(rabbitmq, login)
            password: config(rabbitmq, password)
            virtual_host: config(rabbitmq, virtual_host)
            ssl: config(rabbitmq, ssl)
            ca_certs: config(rabbitmq, ca_certs)

      - If: not (null in $.regionConfigs.keys())
        Then:
        - $.regionConfigs: $.regionConfigs.set(null => $defaultRegionConfig)

      - If: $homeRegion != null and not ($homeRegion in $.regionConfigs.keys())
        Then:
        - $.regionConfigs: $.regionConfigs.set($homeRegion => $defaultRegionConfig)
