<?php

namespace Sso\BackendBundle\Api\Import\Worker;

use Sso\BackendBundle\Api\Manager as ApiManager;
use Sso\BackendBundle\Database\Manager as DbManager;
use Ddeboer\DataImport\Reader\ExcelReader;
use Guzzle\Http\Exception\ClientErrorResponseException;

class Worker
{
    /**
     * @var array
     */
    protected $setter;

    /**
     * @var ApiManager
     */
    protected $apiM;

    /**
     * @var DbManager
     */
    protected $dbM;

    /**
     * @var \Sso\BackendBundle\Database\Manager
     */
    protected $dbBackendManager;

    /**
     * @var \Sso\Webservices\ObjectBundle\Database\Manager
     */
    protected $dbObjectManager;

    /**
     * @param ApiManager $apiM
     */
    public function __construct(ApiManager $apiM)
    {
        $this->apiM = $apiM;
        $this->dbBackendManager = $this->apiM->getContainer()->get('db_backend_manager');
        $this->dbObjectManager = $this->apiM->getContainer()->get('object_database_manager');
    }

    /**
     * @param string $fullFilePath
     * @param string $objectType
     */
    public function objectExcelImport($fullFilePath, $objectType)
    {
        set_time_limit(0);
        ob_implicit_flush(true);
        if ($this->apiM->getContainer()->has('profiler')) {
            $this->apiM->getContainer()->get('profiler')->disable();
        }
        $file = new \SplFileObject($fullFilePath);
        $reader = new ExcelReader($file);
        $reader->setHeaderRowNumber(0);
        $objectTypeEntity = $this->dbObjectManager->respository()->type()->find($objectType);
        $i = 0;
        foreach ($reader as $values) {
            //one object $entity = $this->apiM->getContainer()->get('db_backend_manager')->entity()->import();
            $i++;
            $objectEntity = $this->dbObjectManager->entity()->object();
            foreach ($values as $name => $value) {
                $objectEntity->setType($objectTypeEntity);
                if ($name == 'name') {
                    $objectEntity->setName($value);
                } elseif ($name == 'parent') {
                    if (!empty($value)) {
                        try {
                            $parent = $this->dbObjectManager->respository()->object()->find($value);
                        } catch (\Exception $exc) {
                            $parent = false;
                        }

                        if ($parent) {
                            $objectEntity->setParent($parent);
                        } else {
                            //check for parent with referenceId
                            $searchArray = ['referenceId' => $value];
                            $parent = $this->dbObjectManager->respository()->object()->findOneBy($searchArray);
                            if ($parent) {
                                $objectEntity->setParent($parent);
                            }
                        }
                    }
                } elseif ($name == 'active') {
                    $objectEntity->setActive($value);
                } elseif ($name == 'referenceId') {
                    $objectEntity->setReferenceId($value);
                } else {

                    if (!empty($name) && !empty($value)) {

                        //check guid
                        $entity = $this->dbBackendManager->repository()->import()->findOneBy(['columnName' => $name]);
                        if ($entity) {


                            $attributeValue = $this->dbObjectManager->respository()->attribute()->find(
                                $entity->getObjectValueId()
                            );
                            if ($attributeValue) {
                                $objectAttributeValue = $this->dbObjectManager->entity()->objectAttributeValue();
                                $objectAttributeValue->setAttribute($attributeValue);
                                $objectAttributeValue->setValue($value);
                                $lang = $this->dbObjectManager->respository()->language()->find('en');
                                $objectAttributeValue->setLanguage($lang);
                                $objectAttributeValue->setObject($objectEntity);

                                try {
                                    $em = $this->dbObjectManager->entityManager();
                                    $em->getConnection()->getConfiguration()->setSQLLogger(null);
                                    $em->persist($objectAttributeValue);
                                    $em->flush($objectAttributeValue);
                                } catch (\Exception $exec) {
                                    $this->apiM->log()->error($exec->getMessage());
                                }

                            }
                        }

                    }
                }

            }

            if ($objectEntity->getName()) {
                try {
                    $em = $this->dbObjectManager->entityManager();
                    $em->getConnection()->getConfiguration()->setSQLLogger(null);
                    $em->persist($objectEntity);
                    $em->flush($objectEntity);
                    $this->apiM->log()->info($i . " - object import - " . $this->formatSizeUnits(memory_get_peak_usage()));
                } catch (\Exception $exec) {
                    $this->apiM->log()->error($exec->getMessage());
                }
            }
        }

        ob_end_flush();
        $this->apiM->getContainer()->get('session')->getFlashBag()->add('info', $i . ' objects imported');
    }

    /**
     * @param integer $bytes
     * @return string
     */
    public function formatSizeUnits($bytes)
    {
        if ($bytes >= 1073741824) {
            $bytes = number_format($bytes / 1073741824, 2) . ' GB';
        } elseif ($bytes >= 1048576) {
            $bytes = number_format($bytes / 1048576, 2) . ' MB';
        } elseif ($bytes >= 1024) {
            $bytes = number_format($bytes / 1024, 2) . ' KB';
        } elseif ($bytes > 1) {
            $bytes = $bytes . ' bytes';
        } elseif ($bytes == 1) {
            $bytes = $bytes . ' byte';
        } else {
            $bytes = '0 bytes';
        }

        return $bytes;
    }

}