#!/usr/libexec/platform-python

# Copyright (C) 2011 Oracle. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation, version 2.  This program is distributed in the hope that it will
# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
# Public License for more details.  You should have received a copy of the GNU
# General Public License along with this program; if not, write to the Free
# Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 021110-1307, USA.

### BEGIN PLUGIN INFO
# name: datetime
# configure: 50
# cleanup: 50
# description: Script to configure template datetime.
### END PLUGIN INFO

import json
import os
import re

from templateconfig.cli import main
from templateconfig.common import run_cmd


def set_datetime(datetime):
    year, month, day, hour, minute, sec = datetime.split('-')
    run_cmd(['timedatectl', 'set-time',
             '%s-%s-%s %s:%s:%s' % (year, month, day, hour, minute, sec)])


def set_timezone(timezone, local_rtc):
    run_cmd(['timedatectl', 'set-timezone', timezone])
    run_cmd(['timedatectl', 'set-local-rtc', local_rtc])


def set_ntp(servers, local_time_source=False):
    ntp_conf = '/etc/ntp.conf'
    if os.path.exists(ntp_conf):
        ntp_conf_new = '/etc/ntp.conf.new'
        fd_orig = open(ntp_conf)
        fd_new = open(ntp_conf_new, 'w')
        for line in fd_orig:
            if re.match(r'^server\s', line):
                continue
            fd_new.write(line)
        for server in servers:
            fd_new.write('server %s iburst\n' % server)
        if local_time_source and '127.127.1.0' not in servers:
            fd_new.write('server 127.127.1.0 iburst\n')
        fd_orig.close()
        fd_new.close()
        os.rename(ntp_conf_new, ntp_conf)

    chrony_conf = '/etc/chrony.conf'
    if os.path.exists(chrony_conf):
        chrony_conf_new = '/etc/chrony.conf.new'
        fd_orig = open(chrony_conf)
        fd_new = open(chrony_conf_new, 'w')
        for line in fd_orig:
            if re.match(r'^server\s', line):
                continue
            if re.match(r'^local\s', line):
                continue
            fd_new.write(line)
        for server in servers:
            fd_new.write('server %s iburst\n' % server)
        if local_time_source:
            fd_new.write('local stratum 10\n')
        fd_orig.close()
        fd_new.close()
        os.rename(chrony_conf_new, chrony_conf)


def enable_ntp():
    run_cmd(['timedatectl', 'set-ntp', 'yes'])


def disable_ntp():
    run_cmd(['timedatectl', 'set-ntp', 'no'])


def do_enumerate(target):
    param = []
    if target == 'configure':
        param = [
            {'key': 'com.oracle.linux.datetime.datetime',
             'description': 'System date and time in format year-month-day-hour-minute-second, e.g., "2011-4-7-9-2-42".',
             'hidden': True},
            {'key': 'com.oracle.linux.datetime.timezone',
             'description': 'System time zone, e.g., "America/New_York".',
             'hidden': True},
            {'key': 'com.oracle.linux.datetime.utc',
             'description': 'Whether to keep hardware clock in UTC: True or False.',
             'hidden': True},
            {'key': 'com.oracle.linux.datetime.ntp',
             'description': 'Whether to enable NTP service: True or False.',
             'hidden': True},
            {'key': 'com.oracle.linux.datetime.ntp-servers',
             'description': 'NTP servers separated by comma, e.g., "time.example.com,0.example.pool.ntp.org".',
             'hidden': True},
            {'key': 'com.oracle.linux.datetime.ntp-local-time-source',
             'description': 'Whether to enable NTP local time source: True or False.',
             'hidden': True}]
    return json.dumps(param)


def do_configure(param):
    param = json.loads(param)
    datetime = param.get('com.oracle.linux.datetime.datetime', '').strip()
    if datetime:
        set_datetime(datetime)
    timezone = param.get('com.oracle.linux.datetime.timezone', '').strip()
    if timezone:
        utc = param.get('com.oracle.linux.datetime.utc')
        if utc == 'True':
            local_rtc = 'false'
        else:
            local_rtc = 'true'
        set_timezone(timezone, local_rtc)
    ntp = param.get('com.oracle.linux.datetime.ntp')
    if ntp == 'True':
        ntp_servers = param.get('com.oracle.linux.datetime.ntp-servers', '').strip()
        if ntp_servers:
            ntp_servers = ntp_servers.split(',')
        else:
            ntp_servers = []
        ntp_local_time_source = param.get('com.oracle.linux.datetime.ntp-local-time-source')
        if ntp_local_time_source == 'True':
            ntp_local_time_source = True
        else:
            ntp_local_time_source = False
        if ntp_servers or ntp_local_time_source:
            set_ntp(ntp_servers, ntp_local_time_source)
        disable_ntp()
        enable_ntp()
    elif ntp == 'False':
        disable_ntp()
    return json.dumps(param)


def do_cleanup(param):
    param = json.loads(param)
    set_ntp(['0.rhel.pool.ntp.org', '1.rhel.pool.ntp.org', '2.rhel.pool.ntp.org', '3.rhel.pool.ntp.org'])
    return json.dumps(param)


if __name__ == '__main__':
    main(do_enumerate, {'configure': do_configure, 'cleanup': do_cleanup})
