#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# xwot.py - Python tools for the extended Web of Things
# Copyright (C) 2015  Alexander Rüedlinger
#
# 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, either version 3 of the License, or
# (at your option) any later version.
#
# 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, see <http://www.gnu.org/licenses/>

__author__ = 'Alexander Rüedlinger'

from helper import OutputPrinter
from xwot.compiler.frontend import visitor


class SinatraBackendBuilder(visitor.BaseVisitor):

    def __init__(self):
        visitor.BaseVisitor.__init__(self)
        self._out = OutputPrinter()

    def before(self):
        self._out.code([
            '#',
            '# Generated by xwot compiler.',
            '#',
            '# Sinatra xwot application.',
            '#',
            '',
            "require 'sinatra'",
            '',
            'class App < Sinatra::Application',
            '',
            'end'
        ], ["xwot", "app"])

    def after(self):
        self._out.code([
            "require_relative '%s'" % node.name() for node in self._nodes
        ], ["xwot", "app"])

        self._out.code([
            '#',
            '# Generated by xwot compiler.',
            '#',
            '# Sinatra xwot application.',
            '#',
            '',
            "require 'sinatra/base'",
            "require './xwot/app'",
            '',
            "App::run!",
        ], ["runserver"])

    def before_resource(self, node):
        self._out.code([
            '#',
            '# Generated by xwot compiler.',
            '#',
            "# Type:       %s" % node.type(),
            "# Resource:   %s" % node.name(),
            "# Path:       %s" % node.fullpath(),
            '#',
            '',
            "require 'sinatra'",
            '',
            'class App < Sinatra::Application'
        ], ["xwot", node.name()])

    def after_resource(self, node):
        self._out.code([
            'end',
        ], ["xwot", node.name()])

    def handle_entity(self, node):
        self.before_resource(node)
        self._out.code([
            self._out.indent([
                "get '/' do ",
                self._out.indent([
                    '"Hello World at: %s"' % node.fullpath()
                ]),
                'end'
            ]),
        ], ["xwot", node.name()])
        self.after_resource(node)

    def handle_resource(self, node):
        for method in ['get', 'put']:
            self._out.code([
                self._out.indent([
                    '#',
                    "# %s '%s'" % (method.upper(), node.fullpath()),
                    '#',
                    "%s '%s' do " % (method, node.fullpath()),
                        self._out.indent([
                            '"Hello World at: %s"' % node.fullpath()
                        ]),
                    'end'
                ]),
            ], ["xwot", node.name()])

    def handle_device_resource(self, node):
        for method in ['get', 'put']:
            self._out.code([
                self._out.indent([
                    '#',
                    "# %s '%s'" % (method.upper(), node.fullpath()),
                    '#',
                    "%s '%s' do " % (method, node.fullpath()),
                        self._out.indent([
                            '"Hello World at: %s"' % node.fullpath()
                        ]),
                    'end'
                ]),
            ], ["xwot", node.name()])

    def handle_sensor_resource(self, node):
        for method in ['get']:
            self._out.code([
                self._out.indent([
                    '#',
                    "# %s '%s'" % (method.upper(), node.fullpath()),
                    '#',
                    "%s '%s' do " % (method, node.fullpath()),
                        self._out.indent([
                            '"Hello World at: %s"' % node.fullpath()
                        ]),
                    'end'
                ]),
            ], ["xwot", node.name()])

    def handle_tag_resource(self, node):
        for method in ['get']:
            self._out.code([
                self._out.indent([
                    '#',
                    "# %s '%s'" % (method.upper(), node.fullpath()),
                    '#',
                    "%s '%s' do " % (method, node.fullpath()),
                        self._out.indent([
                            '"Hello World at: %s"' % node.fullpath()
                        ]),
                    'end'
                ]),
            ], ["xwot", node.name()])

    def handle_context_resource(self, node):
        for method in ['get', 'put']:
            self._out.code([
                self._out.indent([
                    '#',
                    "# %s '%s'" % (method.upper(), node.fullpath()),
                    '#',
                    "%s '%s' do " % (method, node.fullpath()),
                        self._out.indent([
                            '"Hello World at: %s"' % node.fullpath()
                        ]),
                    'end'
                ]),
            ], ["xwot", node.name()])

    def handle_service_resource(self, node):
        for method in ['get', 'post', 'put', 'delete']:
            self._out.code([
                self._out.indent([
                    '#',
                    "# %s '%s'" % (method.upper(), node.fullpath()),
                    '#',
                    "%s '%s' do " % (method, node.fullpath()),
                        self._out.indent([
                            '"Hello World at: %s"' % node.fullpath()
                        ]),
                    'end'
                ]),
            ], ["xwot", node.name()])

    def handle_actuator_resource(self, node):
        for method in ['put']:
            self._out.code([
                self._out.indent([
                    '#',
                    "# %s '%s'" % (method.upper(), node.fullpath()),
                    '#',
                    "%s '%s' do " % (method, node.fullpath()),
                        self._out.indent([
                            '"Hello World at: %s"' % node.fullpath()
                        ]),
                    'end'
                ]),
            ], ["xwot", node.name()])

    def handle_publisher_resource(self, node):
        for method in ['get', 'post']:
            self._out.code([
                self._out.indent([
                    '#',
                    "# %s '%s'" % (method.upper(), node.fullpath()),
                    '#',
                    "%s '%s' do " % (method, node.fullpath()),
                        self._out.indent([
                            '"Hello World at: %s"' % node.fullpath()
                        ]),
                    'end'
                ]),
            ], ["xwot", node.name()])

    def output(self):
        # get all created files
        files = self._out.flush()
        new_files_dic = {}

        for file_name, code in files.items():
            # append to each file its correct file extension
            new_files_dic[file_name + ".rb"] = code

        return new_files_dic