<?php

/*
 * This file is part of Anis Server.
 *
 * (c) Laboratoire d'Astrophysique de Marseille / CNRS
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
declare(strict_types=1);

namespace App\Action;

use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;
use Slim\Exception\HttpBadRequestException;
use Slim\Exception\HttpNotFoundException;
use App\Entity\Instance;

/**
 * @author François Agneray <francois.agneray@lam.fr>
 * @package App\Action
 */
final class InstanceAction extends AbstractAction
{
    /**
     * `GET` Returns the instance found
     * `PUT` Full update the instance and returns the new version
     * `DELETE` Delete the instance found and return a confirmation message
     *
     * @param  ServerRequestInterface $request  PSR-7 This object represents the HTTP request
     * @param  ResponseInterface      $response PSR-7 This object represents the HTTP response
     * @param  string[]               $args     This table contains information transmitted in the URL (see routes.php)
     *
     * @return ResponseInterface
     */
    public function __invoke(
        ServerRequestInterface $request,
        ResponseInterface $response,
        array $args
    ): ResponseInterface {
        if ($request->getMethod() === OPTIONS) {
            return $response->withHeader('Access-Control-Allow-Methods', 'GET, PUT, DELETE, OPTIONS');
        }

        // Search the correct instance with primary key
        $instance = $this->em->find('App\Entity\Instance', $args['name']);

        // If instance is not found 404
        if (is_null($instance)) {
            throw new HttpNotFoundException(
                $request,
                'Instance with name ' . $args['name'] . ' is not found'
            );
        }

        if ($request->getMethod() === GET) {
            $payload = json_encode($instance);
        }

        if ($request->getMethod() === PUT) {
            $parsedBody = $request->getParsedBody();

            // To work this action needs information to update instance
            $fields = array(
                'label',
                'description',
                'scientific_manager',
                'instrument',
                'wavelength_domain',
                'display',
                'data_path',
                'files_path',
                'public',
                'portal_logo',
                'design_color',
                'design_background_color',
                'design_logo',
                'design_favicon',
                'navbar_background_color',
                'navbar_border_bottom_color',
                'navbar_color_href',
                'navbar_font_family',
                'navbar_sign_in_btn_color',
                'navbar_user_btn_color',
                'footer_background_color',
                'footer_border_top_color',
                'footer_text_color',
                'footer_logos',
                'family_border_color',
                'family_header_background_color',
                'family_title_color',
                'family_title_bold',
                'family_background_color',
                'family_color',
                'progress_bar_title',
                'progress_bar_title_color',
                'progress_bar_subtitle',
                'progress_bar_subtitle_color',
                'progress_bar_step_dataset_title',
                'progress_bar_step_criteria_title',
                'progress_bar_step_output_title',
                'progress_bar_step_result_title',
                'progress_bar_color',
                'progress_bar_active_color',
                'progress_bar_circle_color',
                'progress_bar_circle_icon_color',
                'progress_bar_circle_icon_active_color',
                'progress_bar_text_color',
                'result_header_background_color',
                'result_header_text_color',
                'result_header_btn_color',
                'result_header_btn_hover_color',
                'result_header_btn_text_color',
                'result_datatable_bordered',
                'result_datatable_border_color',
                'result_datatable_header_background_color',
                'result_datatable_header_text_color',
                'result_datatable_rows_background_color',
                'result_datatable_rows_text_color',
                'result_datatable_sorted_color',
                'result_datatable_sorted_active_color',
                'result_datatable_link_color',
                'result_datatable_link_hover_color',
                'result_datatable_rows_selected_color',
                'samp_enabled',
                'back_to_portal',
                'user_menu_enabled',
                'search_by_criteria_allowed',
                'search_by_criteria_label',
                'search_multiple_allowed',
                'search_multiple_label',
                'search_multiple_all_datasets_selected',
                'documentation_allowed',
                'documentation_label'
            );

            // If mandatories empty fields 400
            foreach ($fields as $a) {
                if (!array_key_exists($a, $parsedBody)) {
                    throw new HttpBadRequestException(
                        $request,
                        'Param ' . $a . ' needed to edit the instance'
                    );
                }
            }

            $this->editInstance($instance, $parsedBody);
            $payload = json_encode($instance);
        }

        if ($request->getMethod() === DELETE) {
            $name = $instance->getName();
            $this->em->remove($instance);
            $this->em->flush();
            $payload = json_encode(array('message' => 'Instance with name ' . $name . ' is removed!'));
        }

        $response->getBody()->write($payload);
        return $response;
    }

    /**
     * Update instance object with setters
     *
     * @param Instance $instance   The instance to update
     * @param array    $parsedBody Contains the new values ​​of the instance sent by the user
     */
    private function editInstance(Instance $instance, array $parsedBody): void
    {
        $instance->setLabel($parsedBody['label']);
        $instance->setDescription($parsedBody['description']);
        $instance->setScientificManager($parsedBody['scientific_manager']);
        $instance->setInstrument($parsedBody['instrument']);
        $instance->setWavelengthDomain($parsedBody['wavelength_domain']);
        $instance->setDisplay($parsedBody['display']);
        $instance->setDataPath($parsedBody['data_path']);
        $instance->setFilesPath($parsedBody['files_path']);
        $instance->setPublic($parsedBody['public']);
        $instance->setPortalLogo($parsedBody['portal_logo']);
        $instance->setDesignColor($parsedBody['design_color']);
        $instance->setDesignBackgroundColor($parsedBody['design_background_color']);
        $instance->setDesignLogo($parsedBody['design_logo']);
        $instance->setDesignFavicon($parsedBody['design_favicon']);
        $instance->setNavbarBackgroundColor($parsedBody['navbar_background_color']);
        $instance->setNavbarBorderBottomColor($parsedBody['navbar_border_bottom_color']);
        $instance->setNavbarColorHref($parsedBody['navbar_color_href']);
        $instance->setNavbarFontFamily($parsedBody['navbar_font_family']);
        $instance->setNavbarSignInBtnColor($parsedBody['navbar_sign_in_btn_color']);
        $instance->setNavbarUserBtnColor($parsedBody['navbar_user_btn_color']);
        $instance->setFooterBackgroundColor($parsedBody['footer_background_color']);
        $instance->setFooterBorderTopColor($parsedBody['footer_border_top_color']);
        $instance->setFooterTextColor($parsedBody['footer_text_color']);
        $instance->setFooterLogos($parsedBody['footer_logos']);
        $instance->setFamilyBorderColor($parsedBody['family_border_color']);
        $instance->setFamilyHeaderBackgroundColor($parsedBody['family_header_background_color']);
        $instance->setFamilyTitleColor($parsedBody['family_title_color']);
        $instance->setFamilyTitleBold($parsedBody['family_title_bold']);
        $instance->setFamilyBackgroundColor($parsedBody['family_background_color']);
        $instance->setFamilyColor($parsedBody['family_color']);
        $instance->setProgressBarTitle($parsedBody['progress_bar_title']);
        $instance->setProgressBarTitleColor($parsedBody['progress_bar_title_color']);
        $instance->setProgressBarSubtitle($parsedBody['progress_bar_subtitle']);
        $instance->setProgressBarSubtitleColor($parsedBody['progress_bar_subtitle_color']);
        $instance->setProgressBarStepDatasetTitle($parsedBody['progress_bar_step_dataset_title']);
        $instance->setProgressBarStepCriteriaTitle($parsedBody['progress_bar_step_criteria_title']);
        $instance->setProgressBarStepOutputTitle($parsedBody['progress_bar_step_output_title']);
        $instance->setProgressBarStepResultTitle($parsedBody['progress_bar_step_result_title']);
        $instance->setProgressBarColor($parsedBody['progress_bar_color']);
        $instance->setProgressBarActiveColor($parsedBody['progress_bar_active_color']);
        $instance->setProgressBarCircleColor($parsedBody['progress_bar_circle_color']);
        $instance->setProgressBarCircleIconColor($parsedBody['progress_bar_circle_icon_color']);
        $instance->setProgressBarCircleIconActiveColor($parsedBody['progress_bar_circle_icon_active_color']);
        $instance->setProgressBarTextColor($parsedBody['progress_bar_text_color']);
        $instance->setResultHeaderBackgroundColor($parsedBody['result_header_background_color']);
        $instance->setResultHeaderTextColor($parsedBody['result_header_text_color']);
        $instance->setResultHeaderBtnColor($parsedBody['result_header_btn_color']);
        $instance->setResultHeaderBtnHoverColor($parsedBody['result_header_btn_hover_color']);
        $instance->setResultHeaderBtnTextColor($parsedBody['result_header_btn_text_color']);
        $instance->setResultDatatableBordered($parsedBody['result_datatable_bordered']);
        $instance->setResultDatatableBorderColor($parsedBody['result_datatable_border_color']);
        $instance->setResultDatatableHeaderBackgroundColor($parsedBody['result_datatable_header_background_color']);
        $instance->setResultDatatableHeaderTextColor($parsedBody['result_datatable_header_text_color']);
        $instance->setResultDatatableRowsBackgroundColor($parsedBody['result_datatable_rows_background_color']);
        $instance->setResultDatatableRowsTextColor($parsedBody['result_datatable_rows_text_color']);
        $instance->setResultDatatableSortedColor($parsedBody['result_datatable_sorted_color']);
        $instance->setResultDatatableSortedActiveColor($parsedBody['result_datatable_sorted_active_color']);
        $instance->setResultDatatableLinkColor($parsedBody['result_datatable_link_color']);
        $instance->setResultDatatableLinkHoverColor($parsedBody['result_datatable_link_hover_color']);
        $instance->setResultDatatableRowsSelectedColor($parsedBody['result_datatable_rows_selected_color']);
        $instance->setSampEnabled($parsedBody['samp_enabled']);
        $instance->setUserMenuEnabled($parsedBody['user_menu_enabled']);
        $instance->setBackToPortal($parsedBody['back_to_portal']);
        $instance->setSearchByCriteriaAllowed($parsedBody['search_by_criteria_allowed']);
        $instance->setSearchByCriteriaLabel($parsedBody['search_by_criteria_label']);
        $instance->setSearchMultipleAllowed($parsedBody['search_multiple_allowed']);
        $instance->setSearchMultipleLabel($parsedBody['search_multiple_label']);
        $instance->setSearchMultipleAllDatasetsSelected($parsedBody['search_multiple_all_datasets_selected']);
        $instance->setDocumentationAllowed($parsedBody['documentation_allowed']);
        $instance->setDocumentationLabel($parsedBody['documentation_label']);

        $this->em->flush();
    }
}