# Copyright 2016 - Nokia.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import json

from django.utils.translation import gettext_lazy as _

from horizon import forms
from horizon import messages

from mistraldashboard import api
from mistraldashboard.default.utils import convert_empty_string_to_none
from mistraldashboard.handle_errors import handle_errors


class CreateForm(forms.SelfHandlingForm):
    name = forms.CharField(
        max_length=255,
        label=_("Name"),
        help_text=_('Cron Trigger name.'),
        required=True
    )

    workflow_id = forms.ChoiceField(
        label=_('Workflow ID'),
        help_text=_('Select Workflow ID.'),
        widget=forms.Select(
            attrs={'class': 'switchable',
                   'data-slug': 'workflow_select'}
        )
    )

    input_source = forms.ChoiceField(
        label=_('Input'),
        help_text=_('JSON of input values defined in the workflow. '
                    'Select either file or raw content.'),
        choices=[('file', _('File')),
                 ('raw', _('Direct Input'))],
        widget=forms.Select(
            attrs={'class': 'switchable',
                   'data-slug': 'inputsource'}
        )
    )
    input_upload = forms.FileField(
        label=_('Input File'),
        help_text=_('A local input to upload.'),
        widget=forms.FileInput(
            attrs={'class': 'switched',
                   'data-switch-on': 'inputsource',
                   'data-required-when-shown': 'true',
                   'data-inputsource-file': _('Input File')}
        ),
        required=False
    )
    input_data = forms.CharField(
        label=_('Input Data'),
        help_text=_('The raw contents of the input.'),
        widget=forms.widgets.Textarea(
            attrs={'class': 'switched',
                   'data-switch-on': 'inputsource',
                   'data-required-when-shown': 'true',
                   'data-inputsource-raw': _('Input Data'),
                   'rows': 4}
        ),
        required=False
    )

    params_source = forms.ChoiceField(
        label=_('Params'),
        help_text=_('JSON of params values defined in the workflow. '
                    'Select either file or raw content.'),
        choices=[('file', _('File')),
                 ('raw', _('Direct Input'))],
        widget=forms.Select(
            attrs={'class': 'switchable',
                   'data-slug': 'paramssource'}
        )
    )
    params_upload = forms.FileField(
        label=_('Params File'),
        help_text=_('A local input to upload.'),
        widget=forms.FileInput(
            attrs={'class': 'switched',
                   'data-switch-on': 'paramssource',
                   'data-required-when-shown': 'true',
                   'data-paramssource-file': _('Params File')}
        ),
        required=False
    )
    params_data = forms.CharField(
        label=_('Params Data'),
        help_text=_('The raw contents of the params.'),
        widget=forms.widgets.Textarea(
            attrs={'class': 'switched',
                   'data-switch-on': 'paramssource',
                   'data-required-when-shown': 'true',
                   'data-paramssource-raw': _('Params Data'),
                   'rows': 4}
        ),
        required=False
    )
    first_time = forms.CharField(
        label=_('First Time (YYYY-MM-DD HH:MM)'),
        help_text=_('Date and time of the first execution.'),
        widget=forms.widgets.TextInput(),
        required=False
    )
    schedule_count = forms.CharField(
        label=_('Count'),
        help_text=_('Number of desired executions.'),
        widget=forms.widgets.TextInput(),
        required=False
    )
    schedule_pattern = forms.CharField(
        label=_('Pattern (* * * * *)'),
        help_text=_('Cron Trigger pattern, mind the space between each char.'),
        widget=forms.widgets.TextInput(),
        required=False
    )

    def __init__(self, request, *args, **kwargs):
        super(CreateForm, self).__init__(request, *args, **kwargs)
        workflow_list = api.workflow_list(request)
        workflow_id_list = []
        for wf in workflow_list:
            workflow_id_list.append(
                (wf.id, "{id} ({name})".format(id=wf.id, name=wf.name))
            )

        self.fields['workflow_id'].choices = workflow_id_list

    def clean(self):
        cleaned_data = super(CreateForm, self).clean()
        cleaned_data['input'] = ""
        cleaned_data['params'] = ""

        if cleaned_data.get('input_upload'):
            files = self.request.FILES
            cleaned_data['input'] = files['input_upload'].read()
        elif cleaned_data.get('input_data'):
            cleaned_data['input'] = cleaned_data['input_data']

        del(cleaned_data['input_upload'])
        del(cleaned_data['input_data'])

        if len(cleaned_data['input']) > 0:
            try:
                cleaned_data['input'] = json.loads(cleaned_data['input'])
            except Exception as e:
                msg = _('Input is invalid JSON: %s') % str(e)
                raise forms.ValidationError(msg)

        if cleaned_data.get('params_upload'):
            files = self.request.FILES
            cleaned_data['params'] = files['params_upload'].read()
        elif cleaned_data.get('params_data'):
            cleaned_data['params'] = cleaned_data['params_data']

        del(cleaned_data['params_upload'])
        del(cleaned_data['params_data'])

        if len(cleaned_data['params']) > 0:
            try:
                cleaned_data['params'] = json.loads(cleaned_data['params'])
            except Exception as e:
                msg = _('Params is invalid JSON: %s') % str(e)
                raise forms.ValidationError(msg)

        return cleaned_data

    @handle_errors(_("Unable to create Cron Trigger"), [])
    def handle(self, request, data):
        data['input'] = convert_empty_string_to_none(data['input'])
        data['params'] = convert_empty_string_to_none(data['params'])
        data['schedule_pattern'] = convert_empty_string_to_none(
            data['schedule_pattern']
        )
        data['first_time'] = convert_empty_string_to_none(data['first_time'])
        data['schedule_count'] = convert_empty_string_to_none(
            data['schedule_count']
        )

        api.cron_trigger_create(
            request,
            data['name'],
            data['workflow_id'],
            data['input'],
            data['params'],
            data['schedule_pattern'],
            data['first_time'],
            data['schedule_count'],
        )
        msg = _('Successfully created Cron Trigger.')
        messages.success(request, msg)

        return True
