#!python
# encoding: utf-8
"""
resync-simulator: ResourceSync tool for simulating a changing
Web data source.

Created by Bernhard Haslhofer on 2012-04-24.
Includes contributions by Simeon Warner
Copyright 2012-2014, ResourceSync.org. All rights reserved.
"""

import sys
import argparse
import yaml
import logging
import logging.config

from simulator import __version__
from simulator.source import Source
from simulator.http import HTTPInterface

DEFAULT_CONFIG_FILE = 'config/default.yaml'
DEFAULT_LOG_FILE = 'config/logging.yaml'


def main():

    # Define simulator options
    parser = argparse.ArgumentParser(description="ResourceSync Source Simulator (v%s)" % (__version__),
                                     formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    parser.add_argument('--config-file', '-c',
                        default=DEFAULT_CONFIG_FILE,
                        help="the simulation configuration file")
    parser.add_argument('--log-config', '-l',
                        default=DEFAULT_LOG_FILE,
                        help="the logging configuration file")
    parser.add_argument('--port', '-p', type=int,
                        default=8888,
                        help="the HTTP interface port that the server will run on")
    parser.add_argument('--base-uri', '-b',
                        default='',
                        help="the base URI used in documents generated (defaults to http://localhost:port/)")
    parser.add_argument('--spec-version',
                        default='1.1', choices=('1.0', '1.1'),
                        help="follow given ResourceSync specification version. The key difference is that v1.0 "
                             "used lastmod for the time of a change (often also the resource Last-Modificatin "
                             "time but not always). In v1.1 the rs:md datetime attribute in a ChangeList "
                             "indicates the time of the change, and use of lastmod is entirely optional (see "
                             "--add-lastmod)")
    parser.add_argument('--no-lastmod',
                        action="store_true",
                        help="in ResourceSync v1.1 responses the default behavior is to include a lastmod "
                             "with the same timestamp for the last change as expressed in the rs:md datetime "
                             "attribute will be added (except for 'deleted' entries in a ChangeLst). This "
                             "flag has no effect removes the lastmod from responses.")

    args = parser.parse_args()

    # Load the YAML logging configuration file and set up logging
    logconfig = yaml.safe_load(open(args.log_config, 'r'))
    logging.config.dictConfig(logconfig)

    # Load the YAML configuration file
    config = yaml.safe_load(open(args.config_file, 'r'))

    # Set up the source
    source_settings = config['source']
    base_uri = args.base_uri
    if (base_uri == ''):
        base_uri = 'http://localhost:' + str(args.port)
    source = Source(source_settings, base_uri, args.port, args.spec_version, args.no_lastmod)

    # Set up and register the source resource_list (if defined)
    if 'resource_list_builder' in config:
        klass_name = config['resource_list_builder']['class']
        mod = __import__('simulator.source', fromlist=[klass_name])
        resource_list_builder_klass = getattr(mod, klass_name)
        builder = resource_list_builder_klass(source, config['resource_list_builder'])
        source.add_resource_list_builder(builder)

    # Set up and register change memory (if defined)
    if 'changememory' in config:
        klass_name = config['changememory']['class']
        mod = __import__('simulator.changememory', fromlist=[klass_name])
        changemem_klass = getattr(mod, klass_name)
        changememory = changemem_klass(source, config['changememory'])
        source.add_changememory(changememory)

    # Bootstrap the source
    source.bootstrap()

    # Start the Web interface, run the simulation
    # Attach HTTP interface to source
    http_interface = HTTPInterface(source)
    try:
        http_interface.start()
        source.simulate_changes()
    except KeyboardInterrupt:
        print("Exiting...")
    finally:
        http_interface.stop()


if __name__ == '__main__':
    main()
