#!python
#
# Copyright (c) 2021 Cisco Systems, Inc. and/or its affiliates
#
import time
import logging
import json
import argparse

from pxgrid_util import PXGridControl
from pxgrid_util import Config
from pxgrid_util import create_override_url
from pxgrid_util import query

logger = logging.getLogger(__name__)

help_text = '''
Query all endpoints from ISE. This script is intended to be used with pxGrid
and the com.cisco.ise.endpoint service, and will query for endpoints based on
either a create or update timestamp and an order. The order {ASC, DESC} will
determine whether the query returns the oldest or most recent endpoints first
and how the timestamp is used in the underlying query.

For example, if the order is DESC and a create timestamp is provided, the query
will return the most recently created endpoints starting with the create
timestamp and working backwards in time. If the order is ASC and a create
timestamp is provided, the query will return the oldest endpoints starting with
the create timestamp and working forwards in time. The same applies to the
update timestamp, but with the endpoint update time instead of create time.

By default, the script will return up to 1000 endpoints starting with the most
recently created or updated endpoints, but these options can be configured via
command line arguments.

The script will return a list of endpoints in JSON format to STDOUT. 
'''

if __name__ == '__main__':
    config = Config()

    # custom local options set to require at least one of the options
    config.parser.description = help_text
    config.parser.formatter_class=argparse.RawDescriptionHelpFormatter
    config.parser.add_argument(
        '--ep-start-index', type=int, default=0,
        help='start index in endpoint query results to return')
    config.parser.add_argument(
        '--ep-count', type=int, default=1000,
        help='number of endpoints to return')
    config.parser.add_argument(
        '--ep-order', type=str, choices=['ASC', 'DESC'], default='DESC',
        help='order of endpoints to return (ASC or DESC)')

    # must specify a timestamp for either create or update, but not both
    g = config.parser.add_mutually_exclusive_group(required=True)
    g.add_argument(
        '--ep-start-timestamp', type=str,
        help='start timestamp for endpoint query (e.g. 2021-01-01T00:00:00.000+00:00)')
    g.add_argument(
        '--ep-update-timestamp', type=str,
        help='update timestamp for endpoint query (e.g. 2021-01-01T00:00:00.000+00:00)')

    # as we've added custom arguments, trigger parsing explicitly
    config.parse_args()


    #
    # verbose logging if configured
    #
    if config.verbose:
        handler = logging.StreamHandler()
        handler.setFormatter(logging.Formatter('%(asctime)s:%(name)s:%(levelname)s:%(message)s'))
        logger.addHandler(handler)
        logger.setLevel(logging.DEBUG)

        # and set for stomp and ws_stomp modules also
        for modname in ['pxgrid_util.stomp', 'pxgrid_util.ws_stomp', 'pxgrid_util.pxgrid']:
            s_logger = logging.getLogger(modname)
            handler.setFormatter(logging.Formatter('%(asctime)s:%(name)s:%(levelname)s:%(message)s'))
            s_logger.addHandler(handler)
            s_logger.setLevel(logging.DEBUG)

    pxgrid = PXGridControl(config=config)

    while pxgrid.account_activate()['accountState'] != 'ENABLED':
        time.sleep(60)

    # lookup for endpoint service
    service_lookup_response = pxgrid.service_lookup('com.cisco.ise.endpoint')
    service = service_lookup_response['services'][0]
    node_name = service['nodeName']
    url = service['properties']['restBaseUrl'] + '/getEndpoints'

    # log url to see what we get via discovery
    logger.info('Using URL %s', url)

    # check to see if we need to override the URL
    if config.discovery_override:
        url = create_override_url(config, url)

    secret = pxgrid.get_access_secret(node_name)['secret']
    logger.info('Using access secret %s', secret)
    payload = {
        # 'startCreateTimestamp': config.config.ep_start_timestamp,
        # 'startUpdateTimestamp': config.config.ep_update_timestamp,
        'count': config.config.ep_count,
        'order': config.config.ep_order,
        'startIndex': config.config.ep_start_index,
        'skipConfigCheck': True,
    }
    if config.config.ep_update_timestamp:
        payload['startUpdateTimestamp'] = config.config.ep_update_timestamp
    else:
        payload['startCreateTimestamp'] = config.config.ep_start_timestamp
    resp = query(config, secret, url, json.dumps(payload))
    print(json.dumps(json.loads(resp), indent=2, sort_keys=True))
