#!/usr/bin/python
# -*- coding: utf-8 -*-

from __future__ import absolute_import, division, print_function
__metaclass__ = type

#  Copyright 2019 Palo Alto Networks, Inc
#
#  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.

ANSIBLE_METADATA = {'metadata_version': '1.1',
                    'status': ['preview'],
                    'supported_by': 'community'}


DOCUMENTATION = '''
---
module: panos_vlan
short_description: Configures VLANs.
description:
    - Manage PAN-OS VLANs.
author: "Garfield Lee Freeman (@shinmog)"
version_added: "2.8"
requirements:
    - pan-python
    - pandevice
extends_documentation_fragment:
    - panos.transitional_provider
    - panos.state
    - panos.vsys_import
    - panos.full_template_support
notes:
    - Checkmode is supported.
    - Panorama is supported.
options:
    name:
        description:
            -  Name of the VLAN.
        required: True
    interface:
        description:
            -  List of interface names
        type: list
    virtual_interface:
        description:
            - The VLAN interface
            - See M(panos_vlan_interface)
'''

EXAMPLES = '''
- name: Create VLAN
  panos_vlan:
    provider: '{{ provider }}'
    name: 'Internal'
    virtual_interface: 'vlan.2'
'''

RETURN = '''
# Default return values
'''

from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.network.panos.panos import get_connection


try:
    from pandevice.network import Vlan
    from pandevice.errors import PanDeviceError
except ImportError:
    pass


def main():
    helper = get_connection(
        vsys_importable=True,
        template=True,
        template_stack=True,
        with_state=True,
        with_classic_provider_spec=True,
        argument_spec=dict(
            name=dict(required=True, ),
            interface=dict(type='list', ),
            virtual_interface=dict(),
        ),
    )

    module = AnsibleModule(
        argument_spec=helper.argument_spec,
        supports_check_mode=True,
        required_one_of=helper.required_one_of,
    )

    parent = helper.get_pandevice_parent(module)

    spec = {
        'name': module.params['name'],
        'interface': module.params['interface'],
        'virtual_interface': module.params['virtual_interface'],
    }
    obj = Vlan(**spec)

    try:
        listing = Vlan.refreshall(parent, matching_vsys=False)
    except PanDeviceError as e:
        module.fail_json(msg='Failed refresh: {0}'.format(e))

    reference_params = {
        'refresh': True,
        'update': not module.check_mode,
        'return_type': 'bool',
    }
    parent.add(obj)

    changed = False
    if module.params['state'] == 'present':
        for vlan in listing:
            if vlan.name != obj.name:
                continue
            if not vlan.equal(obj, compare_children=False):
                changed = True
                obj.extend(vlan.children)
                if not module.check_mode:
                    try:
                        obj.apply()
                    except PanDeviceError as e:
                        module.fail_json(msg='Failed apply: {0}'.format(e))
            break
        else:
            changed = True
            if not module.check_mode:
                try:
                    obj.create()
                except PanDeviceError as e:
                    module.fail_json(msg='Failed create: {0}'.format(e))
        try:
            changed |= obj.set_vsys(module.params['vsys'], **reference_params)
        except PanDeviceError as e:
            module.fail_json(msg='Failed setref: {0}'.format(e))
    elif module.params['state'] == 'absent':
        try:
            changed |= obj.set_vsys(None, **reference_params)
        except PanDeviceError as e:
            module.fail_json(msg='Failed setref: {0}'.format(e))
        if obj.name in [x.name for x in listing]:
            changed = True
            if not module.check_mode:
                try:
                    obj.delete()
                except PanDeviceError as e:
                    module.fail_json(msg='Failed delete: {0}'.format(e))

    module.exit_json(changed=changed, msg='done')


if __name__ == '__main__':
    main()
