#  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:
  std: io.murano
  =: io.murano.resources
  sys: io.murano.system

Name: CinderVolume

Extends:
  - Volume
  - MetadataAware

Properties:
  name:
    Contract: $.string()

  size:
    Contract: $.int().notNull().check($ >= 1)

  availabilityZone:
    Contract: $.string()

  readOnly:
    Contract: $.bool().notNull()
    Default: false

  multiattach:
    Contract: $.bool().notNull()
    Default: false

  sourceImage:
    Contract: $.string()

  sourceVolume:
    Contract: $.class(Volume)

  sourceSnapshot:
    Contract: $.class(CinderVolumeSnapshot)

  sourceVolumeBackup:
    Contract: $.class(CinderVolumeBackup)

  attachments:
    Contract: []
    Usage: Out

Methods:
  buildResourceDefinition:
    Body:
    - $properties:
        size: $.size
        metadata: $this.getMetadata($this.getRegion())

    - If: $.availabilityZone != null
      Then:
        $properties.availability_zone: $.availabilityZone
    - If: $.name != null
      Then:
        $properties.name: $.name
    - If: $.sourceVolumeBackup != null
      Then:
        $properties.backup_id: $.sourceVolumeBackup.openstackId
    - If: $.sourceImage != null
      Then:
        $properties.image: $.sourceImage
    - If: $.sourceSnapshot != null
      Then:
        $properties.snapshot_id: $.sourceSnapshot.openstackId
    - If: $.sourceVolume != null
      Then:
        $properties.source_volid: $.sourceVolume.openstackId

    # Available only since Heat 6.0.0 (Mitaka)
    - If: $.multiattach
      Then:
        $properties.multiattach: $.multiattach

    # Available only since Heat 5.0.0 (Liberty)
    - If: $.readOnly
      Then:
        $properties.read_only: $.readOnly

    - Return:
        resources:
          format('vol-{0}', id($)):
            type: $this.getResourceType()
            properties: $properties
        outputs:
          format('vol-{0}-id', id($)):
            value: $.getRef()
          format('vol-{0}-attachments', id($)):
            value:
              get_attr: [$.getResourceName(), attachments_list]

  deploy:
    Body:
    - $region: $.getRegion()
    - If: $.sourceSnapshot != null
      Then:
        $.sourceSnapshot.validate()
    - If: $.sourceVolumeBackup != null
      Then:
        $.sourceVolumeBackup.validate()
    - If: $.sourceVolume != null
      Then:
        $.sourceVolume.deploy()

    - $snippet: $.buildResourceDefinition()
    - If: $.getAttr(lastTemplate) != $snippet
      Then:
      - $template: $region.stack.current()
      - $template: $template.mergeWith($snippet, maxLevels => 2)
      - $region.stack.setTemplate($template)
      - $region.stack.push()
      - $outputs: $region.stack.output()
      - $.openstackId: $outputs.get(format('vol-{0}-id', id($)))
      - $.setAttr(lastTemplate, $snippet)

  releaseResources:
    Body:
    - If: $.getAttr(lastTemplate) != null
      Then:
      - $region: $.getRegion()
      - $template: $region.stack.current()
      - $template.resources: $template.resources.delete(format('vol-{0}', id($)))
      - $template.outputs: $template.outputs.delete(format('vol-{0}-id', id($)))
      - $region.stack.setTemplate($template)
      - $region.stack.push()
      - $.setAttr(lastTemplate, null)
      - $.openstackId: null
      - $.attachments: null

  getRef:
    Body:
      Return:
        get_resource: format('vol-{0}', id($))

  getResourceName:
    Body:
      Return:
        format('vol-{0}', id($))

  getResourceType:
    Body:
      - Return: 'OS::Cinder::Volume'

  setAttachments:
    Arguments:
      - attachments:
          Contract: []
    Body:
      - $.attachments: $attachments
