#!/usr/bin/python
#-*- coding:utf-8 -*-

# LXCF - LXC Facility
# Copyright (C) 2014 FUJITSU LIMITED

# 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
# of the License.
#
# 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., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.

#
# A scripts for creating LXC domain in which some daemons are running.
# running systemd, rsyslog, sshd in a container.
#

import os, sys
import api_common
import wsgiref, StringIO, datetime
from wsgiref.simple_server import *
from wsgiref import util, simple_server
from SocketServer import *
import ConfigParser

CONFIG_FILE = "/etc/lxcf/lxcf.conf"

# check daemon mode
argvs = sys.argv
argc = len(argvs)
if (argc == 2):
    if (argvs[1] == "-D"):
        fpid = os.fork()
        if (fpid != 0):
            sys.exit(0)

# read the config file
try:
    conf = ConfigParser.SafeConfigParser()
    conf.read(CONFIG_FILE)
    hostname = conf.get("rest_api", "ipaddr")
    port = int(conf.get("rest_api", "port"))
except:
    hostname = 'localhost'
    port = 8080

path_dirs = { \
'/lxcfv1/autostart':api_common.api_autostart(api_common.call_autostart), \
'/lxcfv1/autostart-n':api_common.api_autostart_n(api_common.call_autostart_n), \
'/lxcfv1/blkio_r':api_common.api_blkio_r(api_common.call_blkio_r), \
'/lxcfv1/blkio_w':api_common.api_blkio_w(api_common.call_blkio_w), \
'/lxcfv1/blkiops_r':api_common.api_blkiops_r(api_common.call_blkiops_r), \
'/lxcfv1/blkiops_w':api_common.api_blkiops_w(api_common.call_blkiops_w), \
'/lxcfv1/clone':api_common.api_clone(api_common.call_clone), \
'/lxcfv1/clone-n':api_common.api_clone_n(api_common.call_clone_n), \
'/lxcfv1/cpun':api_common.api_cpun(api_common.call_cpun), \
'/lxcfv1/cpurate':api_common.api_cpurate(api_common.call_cpurate), \
'/lxcfv1/erase':api_common.api_erase(api_common.call_erase), \
'/lxcfv1/erase-n':api_common.api_erase_n(api_common.call_erase_n), \
'/lxcfv1/export-docker':api_common.api_export_docker(api_common.call_export_docker), \
'/lxcfv1/helpcmd':api_common.api_helpcmd(api_common.call_helpcmd), \
'/lxcfv1/list':api_common.api_list(api_common.call_list), \
'/lxcfv1/log':api_common.api_log(api_common.call_log), \
'/lxcfv1/memlimit':api_common.api_memlimit(api_common.call_memlimit), \
'/lxcfv1/memswlimit':api_common.api_memswlimit(api_common.call_memswlimit), \
'/lxcfv1/net_cls':api_common.api_net_cls(api_common.call_net_cls), \
'/lxcfv1/numa':api_common.api_numa(api_common.call_numa), \
'/lxcfv1/q':api_common.api_q(api_common.call_q), \
'/lxcfv1/queue':api_common.api_queue(api_common.call_queue), \
'/lxcfv1/reboot':api_common.api_reboot(api_common.call_reboot), \
'/lxcfv1/rename':api_common.api_rename(api_common.call_rename), \
'/lxcfv1/restore':api_common.api_restore(api_common.call_restore), \
'/lxcfv1/resume':api_common.api_resume(api_common.call_resume), \
'/lxcfv1/resume-n':api_common.api_resume_n(api_common.call_resume_n), \
'/lxcfv1/set':api_common.api_set(api_common.call_set), \
'/lxcfv1/set-n':api_common.api_set_n(api_common.call_set_n), \
'/lxcfv1/show':api_common.api_show(api_common.call_show), \
'/lxcfv1/snapshot':api_common.api_snapshot(api_common.call_snapshot), \
'/lxcfv1/snapshot-list':api_common.api_snapshot_list(api_common.call_snapshot_list), \
'/lxcfv1/snapshot-erase':api_common.api_snapshot_erase(api_common.call_snapshot_erase), \
'/lxcfv1/snapshot-n':api_common.api_snapshot_n(api_common.call_snapshot_n), \
'/lxcfv1/start':api_common.api_start(api_common.call_start), \
'/lxcfv1/start-n':api_common.api_start_n(api_common.call_start_n), \
'/lxcfv1/stop':api_common.api_stop(api_common.call_stop), \
'/lxcfv1/stop-n':api_common.api_stop_n(api_common.call_stop_n), \
'/lxcfv1/submit':api_common.api_submit(api_common.call_submit), \
'/lxcfv1/suspend':api_common.api_suspend(api_common.call_suspend), \
'/lxcfv1/suspend-n':api_common.api_suspend_n(api_common.call_suspend_n), \
'/lxcfv1/sysgen':api_common.api_sysgen(api_common.call_sysgen), \
'/lxcfv1/sysgen-n':api_common.api_sysgen_n(api_common.call_sysgen_n), \
'/lxcfv1/version':api_common.api_version(api_common.call_version), \
'/lxcfv1/snapshot-pull-data':api_common.api_snapshot_pull_data(), \
'/lxcfv1/snapshot-pull':api_common.api_snapshot_pull(api_common.call_snapshot_pull), \
}

class ThreadingWsgiServer(ThreadingMixIn, WSGIServer):
    pass

def Err404(environ, start_response):
    start_response('404 NotFound', [('Content-type', 'text/plain')])
    return '%s is not found' % util.request_uri(environ)

class SelectAPI(object):
    def __init__(self, table):
        path_fun = sorted(table, key=lambda x:len(x), reverse=True)
        table = [(i, table[i]) for i in path_fun]
        self.table = table

    def __call__(self, environ, start_response):
        name = 'SCRIPT_NAME'
        info = 'PATH_INFO'

        scriptname = environ.get(name, '')
        pathinfo = environ.get(info, '')

        for pp, func in self.table:
            if pp == '' or pp == '/' and pathinfo.startswith(pp):
                return func(environ, start_response)

            if pathinfo == pp or pathinfo.startswith(pp) and \
                    pathinfo[len(pp)] == '/':

                scriptname = scriptname + pp
                pathinfo = pathinfo[len(pp):]
                environ[name] = scriptname
                environ[info] = pathinfo
                return func(environ, start_response)
        return Err404(environ, start_response)

if __name__ == '__main__':
    application = SelectAPI(path_dirs)
    s = simple_server.make_server(hostname, port, application, ThreadingWsgiServer)
    s.serve_forever()



