#!/usr/bin/env python
#
# Exercise the opsramp module as an illustration of how to use it.
#
# (c) Copyright 2019-2020 Hewlett Packard Enterprise Development LP
#
# 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.

from __future__ import print_function
import os
import yaml

import opsramp.binding
import opsramp.rba
import opsramp.msp


CATEGORY_NAME = 'python-opsramp test category'


def main():
    OPSRAMP_URL = os.environ['OPSRAMP_URL']
    TENANT_ID = os.environ['OPSRAMP_TENANT_ID']
    KEY = os.environ['OPSRAMP_KEY']
    SECRET = os.environ['OPSRAMP_SECRET']

    ormp = opsramp.binding.connect(OPSRAMP_URL, KEY, SECRET)

    # Print some random global "stuff" just to show that we can.
    cfg = ormp.config()
    print('alert types', cfg.get_alert_types())
    print('channels', cfg.get_channels())
    print('countries', len(cfg.get_countries()))
    print('timezones', len(cfg.get_timezones()))
    print('alert technologies', len(cfg.get_alert_technologies()))
    print('nocs', len(cfg.get_nocs()))
    print('device types', len(cfg.get_device_types()))

    # Focus on a specific tenant.
    tenant = ormp.tenant(TENANT_ID)

    if tenant.is_client():
        print('List the First Response Policies on tenant', TENANT_ID)
        group = tenant.first_response()
        found = group.search()
        print(found['totalResults'], 'first response policies')
        print(yaml.dump(found['results'], default_flow_style=False))

    if tenant.is_client():
        print('List the Service Maps on tenant', TENANT_ID)
        group = tenant.service_maps()
        found = group.get(minimal=True)
        print(len(found), 'service maps')
        print(yaml.dump(found, default_flow_style=False))

    print('List the RBAC permission sets on tenant', TENANT_ID)
    group = tenant.permission_sets()
    found = group.search()
    print(found['totalResults'], 'permission_sets')
    print(yaml.dump(found['results'], default_flow_style=False))

    print('List the RBAC roles on tenant', TENANT_ID)
    group = tenant.roles()
    found = group.search()
    print(found['totalResults'], 'roles')
    print(yaml.dump(found['results'], default_flow_style=False))

    print('List the Sites on tenant', TENANT_ID)
    group = tenant.sites()
    found = group.search()
    print(found['totalResults'], 'sites')
    print(yaml.dump(found['results'], default_flow_style=False))

    print('List the integrations on tenant', TENANT_ID)
    integs = tenant.integrations()
    group = integs.itypes()
    found = group.search()
    print(found['totalResults'], 'integration types')
    print(yaml.dump(found['results']))

    print('Define new custom integrations on', TENANT_ID)
    group = integs.instances()
    for atype in ('OAUTH2', 'BASIC'):
        newcint = group.mkCustom(
            display_name='Example %s integration' % atype,
            inbound_auth_type=atype
        )
        print(yaml.dump(newcint))
        # uncomment the following lines to actually create the integration.
        # if tenant.is_client():
        #     resp = group.create('CUSTOM', newcint)
        #     group.redact_response(resp)
        #     print(resp)

    found = group.search()
    print(found['totalResults'], 'integration instances')
    # "found" contains a complete description of each integration but let's
    # pull them individually anyway and assert that this gives same result.
    print('GET the integrations individually and compare')
    for i in found['results']:
        print('...', i['id'], i['integration']['id'],
              '"' + i.get('displayName', '<no name>') + '"')
        direct = group.get(i['id'])
        assert direct == i

    # Retrieve the agent installation script for this client. The string
    # that OpsRamp returns will contain keys for the client so just print
    # its length and first line to show that we got something.
    if tenant.is_client():
        print('agent installation script for client', TENANT_ID)
        agent_script = tenant.get_agent_script()
        print('length', len(agent_script))
        print(agent_script.split('\n')[0])
        print('')
    else:
        print('List the clients of tenant', TENANT_ID)
        group = tenant.clients()
        clist = group.get()
        print(len(clist), 'clients')
        print(yaml.dump(clist, width=150))
        for c in group.get():
            print('client', yaml.dump(c, width=150).strip())
            resp = group.get(c['uniqueId'])
            print('createdBy', yaml.dump(resp['createdBy'], width=150))
        print('Exercise the create-client code')
        cdef = group.mkClient(
            name='test client 99',
            address='Death Valley',
            time_zone='America/Los_Angeles',
            country='United States')
        print(yaml.dump(cdef))
        # uncomment these lines to actually create the client.
        # resp = group.create(cdef)
        # print(resp)

    print('List the Resources on tenant', TENANT_ID)
    if tenant.is_client():
        group = tenant.resources()
        found = group.minimal()
        print(found['totalResults'], 'resources')
        print(yaml.dump(found['results']))
    else:
        print('<clients only>')

    print('List the monitoring templates on tenant', TENANT_ID)
    monitoring = tenant.monitoring()
    templates = monitoring.templates()
    resp = templates.search()
    print(resp['totalResults'], 'templates')
    # There are typically hundreds of templates so don't YAML dump them.
    for t in resp['results']:
        print('...', t['name'])

    # list the RBA script categories and find or create the one we want.
    print('List the RBA categories on tenant', TENANT_ID)
    rba = tenant.rba()
    group = rba.categories()
    clist = group.get()
    print(len(clist), 'categories')
    print(yaml.dump(clist))
    for c in clist:
        if c['name'] == CATEGORY_NAME:
            cid = c['id']
            break
    else:
        # resp = group.create(CATEGORY_NAME)
        # cid = resp['id']
        print('Category {} not found'.format(CATEGORY_NAME))
        cid = None

    if cid:
        print('Scripts in category', cid)
        cobj = group.category(cid)
        slist = cobj.get()
        print(len(slist), 'scripts')
        for s in slist:
            print('...', s['id'], s['name'])
            direct = cobj.get(s['id'])
            assert s == direct

        # Create a new RBA script in this category with one parameter. You can
        # see from the "payload" that this gets passed to the script as $1
        p1 = cobj.mkParameter(
            name='venue',
            description='Where am I today?',
            datatype='STRING'
        )
        print('Parameter definition struct')
        print(yaml.dump(p1))
        s1 = cobj.mkScript(
            name='Hello <venue>',
            description='Stereotypical rock star intro',
            platforms=['LINUX'],
            execution_type='COMMAND',
            payload='echo "hello $1"',
            parameters=[p1]
        )
        print('Script definition struct')
        print(yaml.dump(s1))
        # uncomment these lines to actually create the script.
        # resp = cobj.create(s1)
        # print(resp)

    print('Management policies on tenant', TENANT_ID)
    group = tenant.policies()
    plist = group.get()
    print(len(plist), 'policies')
    for p in plist:
        rules = p['rules']
        actions = p['actions']
        print('...', p['id'], p['uid'], 'name', p['name'],
              'rules', len(rules),
              'actions', len(actions))
        for r in rules:
            print('...... rule', r)
        for a in actions:
            print('...... action', a['action'])
        # plist contains a complete description of each policy
        # but let's pull them individually anyway and assert that
        # this gives the same result.
        direct = group.get(p['id'])
        assert p == direct
    print('')

    print('Credential sets on tenant', TENANT_ID)
    if tenant.is_client():
        cs = tenant.credential_sets()
        resp = cs.get()
        print(resp['totalResults'], 'credential sets')
        print(yaml.dump(resp['results'], default_flow_style=False))
    else:
        print('<clients only>')

    print('Discovery Profiles on tenant', TENANT_ID)
    if tenant.is_client():
        group = tenant.discovery()
        profiles = group.get()
        print(len(profiles), 'profiles')
        for profile in profiles:
            uuid = profile['id']
            name = profile['name']
            print('...', uuid, '"%s"' % name)
            print(yaml.dump(profile))
            direct = group.get(uuid)
            assert direct == profile
        print('')
    else:
        print('<clients only>')

    print('Escalation Policies on tenant', TENANT_ID)
    group = tenant.escalations()
    found = group.search()
    print(found['totalResults'], 'escalation policies')
    print(yaml.dump(found['results'], default_flow_style=False))

    print('Management profiles on tenant', TENANT_ID)
    group = tenant.mgmt_profiles()
    found = group.search()
    print(found['totalResults'], 'management profiles')
    print(yaml.dump(found['results'], default_flow_style=False))


if __name__ == "__main__":
    main()
