<?php

namespace NPS\Model;

use NPS\Entity\FileEntity;
use NPS\Model\User;
use \DateTime;


/**
 * File domain object
 * @author Lukas Korinek
 */
final class File implements IDomainObject
{
    const FILE_IMAGE = 0;
    const FILE_ZIP = 1;
    const FILE_VIDEO = 2;
    const FILE_AUDIO = 3;



    /** @var FileEntity $entity */
    private $entity;

    /** @var User $user User who uploaded the image */
    private $uploader;

    /** @var string $mediaBasePath */
    private $mediaBasePath;

    /** @var string $content */
    private $content;

    public function __construct(FileEntity $entity, User $uploader = null, $mediaBasePath)
    {
        $this->entity = $entity;
        $this->uploader = $uploader;
        $this->mediaBasePath = $mediaBasePath;
        $this->content = null;
    }

    ////////////////////////////////////////////////////////////////////
    // Getters

    /**
     * @inheritdoc
     */
    public function getId() 
    {
        return $this->entity->getId();
    }

    /**
     * @inheritdoc
     */
    public function getEntity()
    {
        return $this->entity;
    }

    /**
     * Gets the creation (upload) date
     * @return DateTime
     */
    public function getDateCreated()
    {
        return $this->entity->dateCreated;
    }

    /**
     * Gets the file uploader
     * @return User
     */
    public function getUploader()
    {
        return $this->user;
    }

    /**
     * Gets original filename
     * @return string 
     */
    public function getFileName()
    {
        return $this->entity->filename;
    }

    /**
     * Gets associated tags
     * @return array
     */
    public function getTags()
    {
        return $this->entity->tags;
    }

    /**
     * Checks if the file has the requested tag
     * @param string $tag 
     * @return bool
     */
    public function hasTag($tag)
    {
        return in_array(strtolower(trim($tag)), $this->getTags());
    }

    /**
     * Gets the file note
     * @return string|null
     */
    public function getNote()
    {
        return $this->entity->note;
    }

    
    /**
     * Gets the file type
     * @return int
     */
    public function getType()
    {
        return $this->entity->type;
    }

    /**
     * Gets the file path
     * @return string
     */
    public function getPath()
    {
        return $this->entity->path;
    }

    /**
     * Gets the real file path
     * @return string
     */
    public function getRealPath()
    {
        return $this->entity->realpath;
    }

    /**
     * Gets final url to the file
     * @return string|null
     */
    public function getUrl()
    {
        // Filemtime is already cached by PHP
        // Use clearstatcache to clear it
        if(!$filemtime = filemtime($this->getRealPath()))
        {
            return null;
        }

        // Where path starts with forward slash
        return $this->mediaBasePath . $this->getPath() . '?' . $filemtime;
    }

    /**
     * Gets the file content
     * @return string
     */
    protected function getContent()
    {
        if(!$this->content)
        {
            $this->content = file_get_contents($this->getRealPath());
        }

        return $this->content;
    }

    /**
     * Gets content checksum
     * @return int
     */
    public function getChecksum()
    {
        return crc32($this->getContent());
    }

    public function __toString()
    {
        return $this->getUrl();
    }

    /////////////////////////////////////////////////

    /**
     * Updates contents of the file
     * @param string $content
     * @return bool True on success
     */
    public function updateContent($content)
    {
        if(empty(trim($content)))
        {
            return false;
        }

        if($this->getChecksum() == crc32($content))
        {
            return true;
        }

        if(file_put_contents($this->getRealPath(), $content) === false)
        {
            return false;
        }

        return true;
    }

}

