#!/usr/bin/env python
import sys, os, errno
import sqlite3
import argparse
from datetime import datetime

def get_logs(cursor, output=None, before=None, after=None, keywords=None):
    query = 'SELECT * FROM logs WHERE 1=1'

    if before:
        query += ' AND time <= {}'.format(int((datetime.strptime(before, '%Y/%m/%d %H:%M:%S') - datetime.fromtimestamp(0)).total_seconds()))
    if after:
        query += ' AND time >= {}'.format(int((datetime.strptime(after, '%Y/%m/%d %H:%M:%S') - datetime.fromtimestamp(0)).total_seconds()))
    if keywords:
        query += ' AND (1=2{})'.format(''.join(' OR msg GLOB "*{}*"'.format(k.strip().replace("'", "''")) for k in keywords.split(',')))

    log_text = ''
    for row in cursor.execute(query):
        log_text += '{level}\t{time}\t{username}:\t{msg}\n'.format(
            level   = row[2],
            time    = datetime.fromtimestamp(int(row[1])).strftime('%Y/%m/%d %H:%M:%S'),
            username= row[3],
            msg     = row[4].encode('utf8'))

    with open(output, 'w') if output else sys.stdout as out:
        out.write(log_text)

def main():
    parser = argparse.ArgumentParser(description='Convert synolog to human readable format.')
    parser.add_argument('database', help='Log database path')
    parser.add_argument('-o', '--output', help='Save converted log to specified file.')
    parser.add_argument('--after', help='Filter logs that after specified time only. Ex: YY/mm/dd HH:MM/SS')
    parser.add_argument('--before', help='Filter logs that before specified time only. Ex: YY/mm/dd HH:MM/SS')
    parser.add_argument('-k', '--keywords', help='Filter logs that included specified keywords only. '\
        + 'keywords can be splited by comma. Ex: "Log, FTP"')

    args = parser.parse_args()

    if not os.path.exists(args.database):
        raise OSError(errno.ENOENT, os.strerror(errno.ENOENT), args.database)

    with sqlite3.connect(args.database) as conn:
        get_logs(conn.cursor(), output=args.output, before=args.before, after=args.after, keywords=args.keywords)


if __name__ == '__main__':
    main()
