<?php
// Copyright (c) Pickware GmbH. All rights reserved.
// This file is part of software that is released under a proprietary license.
// You must not copy, modify, distribute, make publicly available, or execute
// its contents or parts thereof without express permission by the copyright
// holder, unless otherwise permitted by law.

namespace Shopware\Plugins\ViisonCommon\Classes\Plugins\SwagImportExport;

use Enlight_Components_Snippet_Namespace as SnippetNamespace;
use Shopware\Plugins\ViisonCommon\Classes\Plugins\SwagImportExport\SwagImportExportVersion2\SwagAdapterException;
use Shopware\Plugins\ViisonCommon\Classes\Plugins\SwagImportExport\SwagImportExportVersion2\SwagAdapterValidator;
use Shopware_Components_Snippet_Manager as SnippetManager;

class DbAdapterValidator extends SwagAdapterValidator
{
    /**
     * @var SnippetNamespace
     */
    protected $namespace;

    /**
     * @var array
     */
    private $fieldTypes;

    /**
     * @var array
     */
    private $requiredFields;

    /**
     * @param SnippetManager $snippetManager
     * @param array $fieldTypes (optional)
     * @param array $requiredFields (optional)
     */
    public function __construct(SnippetManager $snippetManager, $fieldTypes = [], $requiredFields = [])
    {
        $this->namespace = $snippetManager->getNamespace('backend/plugins/swag_import_export/db_adapter_validator');
        $this->fieldTypes = $fieldTypes;
        $this->requiredFields = $requiredFields;
    }

    /**
     * Checks whether required fields are set.
     *
     * @param array $record
     * @throws SwagAdapterException
     */
    public function checkRequiredFields($record)
    {
        foreach ($this->requiredFields as $fieldName) {
            if (!isset($record[$fieldName])) {
                throw new SwagAdapterException(
                    sprintf($this->namespace->get('validator/error/required_field', 'Field "%s" must not be empty.'), $fieldName)
                );
            }
        }
    }

    /**
     * Validates the types of all fields in the record.
     *
     * @param array $record
     * @throws SwagAdapterException
     */
    public function validateFieldTypes(array $record)
    {
        $this->validate($record, $this->fieldTypes);
    }

    /**
     * @inheritdoc
     */
    public function validate($record, $mapper)
    {
        foreach ($record as $fieldName => $value) {
            foreach ($mapper as $type => $fields) {
                if (!in_array($fieldName, $fields)) {
                    continue;
                }

                // Check for validator
                $methodName = 'validate' . ucfirst($type);
                if (!method_exists($this, $methodName)) {
                    continue;
                }

                // Validate type
                if (!$this->{$methodName}($value)) {
                    $message = $this->namespace->get('validator/error/field_type/message', 'Field "%s" must be of type "%s".');
                    $typeName = $this->namespace->get('validator/error/field_type/type/' . $type, $type);
                    throw new SwagAdapterException(sprintf($message, $fieldName, $typeName));
                }
                break;
            }
        }
    }

    /**
     * Validates fields with 'unsignedInt' type. Values with this type must fulfill 'validateInt' and
     * must not have a negative value.
     *
     * @param $value
     * @return boolean
     */
    public function validateUnsignedInt($value)
    {
        return $this->validateInt($value) && intval($value) >= 0;
    }
}
