#!/usr/bin/env python
# ________________________________________________________________________
#
#  Copyright (C) 2015 Andrew Fullford
#
#  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.
# ________________________________________________________________________
#
 
import os, sys, time, re, argparse, logging, yaml
from logging.handlers import SysLogHandler
from taskforce import utils
from rainbarrel import barrel
 
program = os.path.basename(os.path.splitext(sys.argv[0])[0])
logging_name = program

def_config = {
	'listen': '0.0.0.0',
	'authaddrs': ['127.0.0.1/8', '::1', '192.168.11.0/24', '192.168.122.0/24'],
	'events': '0.0.0.0:1315',
	'certfile': None,
	'datadir': '~/barrel',
	#'authaddrs': None,
	'timestamp_local': True,
	'timestamp_resolution': 'msec',
	'timestamp_terse': False,
}
def_pidfile = os.path.join(def_config['datadir'], program + '.pid')

def load_config(path):
	config = def_config.copy()
	if path:
		with open(path, 'r') as f:
			loaded_config = yaml.safe_load(f)
		config.update(loaded_config)
	return config

p = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter,
	description='Track demand power from Rainforest "Eagle" smart meter monitoring device.')

p.add_argument('-v', '--verbose', action='store_true', dest='verbose', help='Verbose logging for debugging.')
p.add_argument('-q', '--quiet', action='store_true', dest='quiet', help='Quiet logging, warnings and errors only.')
p.add_argument('-e', '--log-stderr', action='store_true', dest='log_stderr', help='Log to stderr instead of syslog.')
p.add_argument('-b', '--background', action='store_true', dest='daemonize', help='Run in the background.')
p.add_argument('-c', '--config', action='store', dest='config_file', metavar='FILE', help='Configuration file')
p.add_argument('-p', '--pidfile', action='store', dest='pidfile', metavar='FILE',
			help='Pidfile path, default "%s", "-" means none.' % (def_pidfile,))

args = p.parse_args()

config = load_config(args.config_file)

pidfile = None
if args.pidfile is None and args.daemonize:
	pidfile = def_pidfile
else:
	pidfile = args.pidfile
if pidfile == '' or pidfile == '-':
	pidfile = None

if pidfile:
	pidfile = os.path.realpath(os.path.expandvars(os.path.expanduser(pidfile)))

if args.daemonize:
	utils.daemonize()

if args.log_stderr:
	log_handler = logging.StreamHandler()
	log_formatter = logging.Formatter(fmt="%(asctime)s %(levelname)s %(message)s")
else:
	logparams = {}
	for addr in ['/dev/log', '/var/run/log']:
		if os.path.exists(addr):
			logparams['address'] = addr
			break
	log_handler = SysLogHandler(**logparams)
	log_formatter = logging.Formatter(fmt="%(name)s[%(process)d]: %(levelname)s %(message).1000s")

log = logging.getLogger(logging_name)
log_handler.setFormatter(log_formatter)
log.addHandler(log_handler)

if args.verbose:
	log.setLevel(logging.DEBUG)
elif args.quiet:
	log.setLevel(logging.WARNING)
else:
	log.setLevel(logging.INFO)

if pidfile is not None:
	try:
		utils.pidclaim(pidfile)
	except Exception as e:
		log.critical('Fatal error -- %s', str(e), exc_info=args.verbose)
		sys.exit(2)

log.info("Started")

barrel = barrel.Barrel(config, log=log)

code = 0
while True:
	try:
		barrel.fill()
	except KeyboardInterrupt:
		log.info("Exiting on interrupt")
		code = 1
		break
	except Exception as e:
		log.error("Unhandled exception -- %s", str(e), exc_info=True)
		time.sleep(0.5)
sys.exit(code)
