#!/usr/bin/env python

########################################
#
# alert-sender - Alert Command-line script
#
########################################

import os
import sys
import argparse

possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
                                                os.pardir,
                                                os.pardir))
if os.path.exists(os.path.join(possible_topdir, 'alerta', '__init__.py')):
    sys.path.insert(0, possible_topdir)

from alerta.common import config, severity_code, status_code
from alerta.common import log as logging
from alerta.sender.client import SenderClient, Version

LOG = logging.getLogger('alerta.sender')
CONF = config.CONF


def main():

    try:
        parser = argparse.ArgumentParser(
            add_help=False,
            prog='alert-sender',
            description='Alert Command-Line Tool - sends an alert to the alerting system. Alerts must have' +
                        ' a resource (including service and environment), event name, value and text. A ' +
                        'severity of "Normal" is used if none given. Tags and group are optional.',
            epilog='alert-sender.py --resource myCoolApp --event AppStatus --group Application --value Down ' +
                   '--severity critical --env PROD --svc MicroApp --tag Release=134 --tag Build=1005 ' +
                   '--text "Micro App X is down."'
        )
        parser.add_argument(
            '-r', '--resource',
            help='Resource under alarm eg. hostname, network device, application, web address.'
        )
        parser.add_argument(
            '-e',
            '--event',
            help='Event name eg. NodeDown, QUEUE:LENGTH:EXCEEDED, coldStart, LOG_ERROR'
        )
        parser.add_argument(
            '-C',
            '--correlate',
            action='append',
            default=list(),
            help='List of events to correlate together eg. node_up and node_down'
        )
        parser.add_argument(
            '-g',
            '--group',
            help='Event group eg. Application, Backup, Database, HA, Hardware, Job, Network, OS, Performance, Security'
        )
        parser.add_argument(
            '-v',
            '--value',
            help='Event value eg. 100%%, Down, PingFail, 55tps, ORA-1664'
        )
        parser.add_argument(
            '--status',
            default='Unknown',
            help='Status eg. Open, Ack, Closed, Unknown (default: %(default)s)'
        )
        parser.add_argument(
            '-s',
            '--severity',
            default='Normal',
            help='Severity eg. Critical, Major, Minor, Warning, Normal, Informational, Debug (default: %(default)s)'
        )
        parser.add_argument(
            '-E',
            '--environment',
            metavar='ENV',
            action='append',
            help='List of effected environments eg. PROD, REL, QA, TEST, CODE, STAGE, DEV, LWP, INFRA'
        )
        parser.add_argument(
            '-S',
            '--svc',
            '--service',
            dest='service',
            action='append',
            help='List of effected services eg. R1, R2, Frontend, Discussion, ContentAPI, MicroApp, ' +
                 'FlexibleContent, Identity, Mobile, Soulmates, Network, SharedSvcs'
        )
        parser.add_argument(
            '-T',
            '--tag',
            action='append',
            dest='tags',
            default=list(),
            help='Add Key=Value tag pairs.'
        )
        parser.add_argument(
            '-t',
            '--text',
            help='Freeform alert text eg. Host not responding to ping.'
        )
        parser.add_argument(
            '--summary',
            metavar='TEXT',
            help='Summary text suitable for SMS, pager or email subject.'
        )
        parser.add_argument(
            '--more',
            dest='more_info',
            metavar='TEXT',
            help='More information eg. a link to a Wiki, ticket number or call reference.'
        )
        parser.add_argument(
            '--graphs',
            action='append',
            dest='graph_urls',
            default=list(),
            metavar='URLS',
            help='List of graph URLs.'
        )
        parser.add_argument(
            '-o',
            '--timeout',
            type=int,
            help='Timeout in seconds that OPEN alert will persist in webapp.'
        )
        parser.add_argument(
            '--type',
            dest='event_type',
            default='exceptionAlert',
            help='Event type eg. exceptionAlert, serviceAlert'
        )
        parser.add_argument(
            '-H',
            '--heartbeat',
            action='store_true',
            default=False,
            help='Send heartbeat to server.'
        )
        parser.add_argument(
            '-O',
            '--origin',
            help='Origin of heartbeat. Usually an application instance.'
        )
        parser.add_argument(
            '-q',
            '--quiet',
            action='store_true',
            default=False,
            help='Do not display assigned alert id.'
        )
        parser.add_argument(
            '-d',
            '--dry-run',
            action='store_true',
            default=False,
            help='Do not send alert. Output as Curl.'
        )

        config.parse_args(version=Version, cli_parser=parser, daemon=False)
        logging.setup('alerta')

        if not CONF.heartbeat:
            if not CONF.resource:
                parser.error("Must supply event resource using -r or --resource")

            if not CONF.event:
                parser.error("Must supply event name using -e or --event")

            CONF.status = status_code.parse_status(CONF.status) or status_code.UNKNOWN
            if CONF.status not in status_code.ALL:
                parser.error("Status must be one of %s" % ','.join(status_code.ALL))

            CONF.severity = severity_code.parse_severity(CONF.severity) or severity_code.NORMAL
            if CONF.severity not in severity_code.ALL:
                parser.error("Severity must be one of %s" % ','.join(severity_code.ALL))

            if CONF.correlate and CONF.event not in CONF.correlate:
                CONF.correlate.append(CONF.event)

            if not CONF.timeout:
                CONF.timeout = CONF.global_timeout

        if CONF.tags:
            CONF.tags = dict([tag.split('=') for tag in CONF.tags])
        else:
            CONF.tags = dict()

        sender = SenderClient()
        msg_id = sender.main()

        if not CONF.quiet:
            print msg_id

    except Exception, e:
        print >> sys.stderr, e
        sys.exit(1)

if __name__ == '__main__':
    main()
