# BFH Science Self-Service Portal
# Copyright (C) 2025-2026 IKUS Software
#
# 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 <https://www.gnu.org/licenses/>.

import cherrypy
from cherrypy_foundation.form import CherryForm
from cherrypy_foundation.tools.i18n import gettext as _
from cherrypy_foundation.url import url_for
from wtforms.fields import HiddenField, StringField, TextAreaField
from wtforms.validators import AnyOf, InputRequired, Length

from bfh_science_ssp.core.const import (
    LNI_CLOUD,
    LNI_COMPUTE,
    LNI_CONSULING,
    LNI_INFRASTRUCTURE,
    LNI_NETWORK,
    LNI_STORAGE,
)


class RequestAccessForm(CherryForm):
    """
    Form used to request access to WLAN, VPN or Nextcloud
    """

    _ressources_table = {
        'SSH Jumphost': LNI_INFRASTRUCTURE,
        'VPN': LNI_INFRASTRUCTURE,
        'WLAN': LNI_NETWORK,
        'Nextcloud': LNI_COMPUTE,
        'Self-Service Portal': LNI_COMPUTE,
    }
    subject = _('Request access')
    service = LNI_NETWORK

    resource = HiddenField(
        validators=[InputRequired(), AnyOf(values=_ressources_table.keys())],
    )
    reason = TextAreaField(
        label=_('Reason for access'),
        validators=[
            InputRequired(),
            Length(max=500, message=_('Maximum length of 500.')),
        ],
        render_kw={
            "rows": "5",
            "style": "height: 100px",
        },
    )

    def validate_resource(self, field):
        # Update subject and service based on resources name.
        self.subject = _('Request access to %s') % self.resource.data
        self.service = self._ressources_table.get(self.resource.data)


class RequestSupportForm(CherryForm):
    """
    Form used to ask for help for any resources.
    """

    service = "LNI Infrastructure"
    subject = _('Support Request')

    resource = StringField(
        label=_('Resource'),
        validators=[InputRequired()],
        render_kw={
            "class": "ssp-locked",
        },
    )

    resource_service = StringField(
        label=_('Service'),
        validators=[
            InputRequired(),
            AnyOf(values=[LNI_CLOUD, LNI_STORAGE, LNI_NETWORK, LNI_COMPUTE, LNI_INFRASTRUCTURE, LNI_CONSULING]),
        ],
        render_kw={
            "class": "ssp-locked",
        },
    )
    message = TextAreaField(
        label=_('Explain your issue'),
        validators=[
            InputRequired(),
            Length(max=4096, message=_('Maximum length of 4096.')),
        ],
        render_kw={
            "rows": "10",
            "style": "height: 250px",
        },
    )

    def get_sources(self):
        # List of typeahead data sources.
        return {
            ' ' + _('other'): {'data': [{'name': _('Anything else'), 'service': LNI_CONSULING}]},
            _('Applications'): {
                'data': [
                    {'name': _('Nextcloud'), 'service': LNI_COMPUTE},
                    {'name': _('Self-Service Portal'), 'service': LNI_COMPUTE},
                ]
            },
            _('Cloud'): {
                'ajax': {
                    'url': url_for('dashboard', 'cloud.json'),
                    'path': 'data',
                },
            },
            _('Compute'): {
                'ajax': {
                    'url': url_for('dashboard', 'compute.json'),
                    'path': 'data',
                },
            },
            _('Infrastructure'): {
                'ajax': {
                    'url': url_for('dashboard', 'infra.json'),
                    'path': 'data',
                },
            },
            _('Storage'): {
                'ajax': {
                    'url': url_for('dashboard', 'storage.json'),
                    'path': 'data',
                },
            },
            _('Network'): {
                'data': [
                    {'name': _('SSH'), 'service': LNI_INFRASTRUCTURE},
                    {'name': _('VPN'), 'service': LNI_INFRASTRUCTURE},
                    {'name': _('WLAN'), 'service': LNI_NETWORK},
                ]
            },
        }

    def validate_resource_service(self, field):
        # Copy the service name to the right property.
        self.service = self.resource_service.data


class RequestAccessHandler:
    """
    Handler for common request.
    """

    @cherrypy.expose()
    @cherrypy.tools.allow(methods=['POST'])
    @cherrypy.tools.ratelimit(method=['POST'])
    def request_access(self, u=None, **kwargs):
        """
        Handle request access form.
        """
        self._send_request(RequestAccessForm())

    @cherrypy.expose()
    @cherrypy.tools.allow(methods=['POST'])
    @cherrypy.tools.ratelimit(method=['POST'])
    def request_support(self, u=None, **kwargs):
        """
        Handle request ask for help form.
        """
        self._send_request(RequestSupportForm())
