<?php  // vim:set et ts=4 sw=4 sts=4:
# Copyright (C) 2003-2014 hipplay Inc.
#
# This is UNPUBLISHED PROPRIETARY SOURCE CODE OF hipplay Inc.
# The copyright notice above does not evidence any actual or intended
# publication of such source code. The contents of this file may not
# be disclosed to third parties, copied or duplicated in any form, in
# whole or in part, without the prior written permission of
# hipplay Inc.
#
namespace HipPlayConnect\FileSystem;


use DOMDocument;
use DOMElement;
use HipPlayConnect\AxDB;

class AxFile
{
    const EXTERNAL_FILESYSTEM = '/home/0external';

    protected $fsPath = null;
	protected $xmlFields = array( 'name', 'href', 'type' );
	protected $sambaPath = null;
	protected $URIBuilder = null;
    protected $data = array();
	
	public function __construct( $fsPath, $sambaPath = null, $URIBuilder = null )
	{
	    $this->URIBuilder = $URIBuilder;
		$this->setFsPath($fsPath);
//		$this->setSambaPath($sambaPath);
//	    $this->setHrefFromPath($fsPath);
	}

    /**
     * Recalculate the fs and samba paths based on the provided path
     *
     * @param $fsPath
     */
    protected function setPathsAndHref( $fsPath )
    {
        if ( !is_null( $this->URIBuilder) ) 
		{
		    $this->setHrefFromPath( $fsPath );
            /** @noinspection PhpUnusedLocalVariableInspection */
            list($newFsPath, $newSambaPath, $res) = call_user_func( array( $this->URIBuilder, 'getPathsForURI' ), $this->data[ 'href' ] );
            $this->setFsPath($newFsPath);
    	    $this->setSambaPath($newSambaPath);
		}    
    }
	
	public function setHrefFromPath($fsPath)
	{	    
	    if ( !is_null( $this->URIBuilder) )
			$this->data[ 'href' ] = call_user_func( array( $this->URIBuilder, 'getURIForFSPath' ),  $fsPath ) ;
	}
	
	/**
	 * Sets the URI of the AxFile without relying on $this->URIBuilder
	 * (used by AxAlbumElement)
	 *
	 * @param string $href the href
	 */
	public function setHref( $href )
	{
	    $this->data[ 'href' ] = $href;
	}
	
	/**
	 * Sets the URI of the parent of the AxFile without relying on $this->URIBuilder
	 * (used by AxAlbumElement)
	 *
	 * @param string $parentHref the href
	 */
	public function setParentHref( $parentHref )
	{
	    $this->data[ 'parentHref' ] = $parentHref;
	}	
	
	public function setFsPath($path)
	{
	    $this->fsPath = $path;	    
	}
	
	public function setSambaPath($path)
	{	   
	    $this->hackSambaPath( $path );	    	
	    $this->data[ 'name' ] = self::getBasename( $path );
	}	
	    
    /**
     * Sets the samba path without changing the name
     *
     * @param string $sambaPath the samba path to use
     */
    public function hackSambaPath( $sambaPath )
    {
        $this->sambaPath = $sambaPath;
        $this->data[ 'path' ] = strtr( $sambaPath, '/', '\\' );
    }	

    // should be overridden, based on this:
	public function getField( $key ) 
	{
		return
			array_key_exists( $key, $this->data )
			? $this->data[ $key ]
			: null;
	}

	/**
	 * Returns the Samba Path of the file (with slashes)
	 *
	 * @return string the Samba Path of the file (with slashes)
	 */
	public function getSambaPath()
	{
		return $this->sambaPath;
	}

	public function getFsPath()
	{
	    return $this->fsPath;	    
	}

    /**
     * Returns an XML string describing the file with great details
     *
     * $doc if not null, it will be used as the document and a DOMElement will be returned
     * $fields if not null, it will be used instead of the default fields list
     *
     * @param DOMDocument $doc
     * @param array       $fields
     *
     * @return string|DOMElement describing the file
     */
	public function getXML( $doc = null, $fields = null )
	{
		$returnText = is_null( $doc );
		if ( is_null( $doc ) )
			$doc = new DOMDocument( '1.0' );

		$root =  $doc->createElement( 'file' ) ;
		
		foreach ( is_null( $fields ) ? $this->xmlFields : $fields as $key ) {
			if ( !is_null( $value = $this->getField( $key ) )  ) 											
				$root->setAttribute( $key, $value );						
		}
			
		if ($returnText) {
			$doc->appendChild($root);
			return $doc->saveXML();
		} else {
			return $root;	
		}
		
	}

	// Warning: do not override static methods, it won't work!
    /**
     * @param object $dbConn
     * @param $what
     *
     * @return array
     */
    public static function getFSPathConditions( $dbConn, $what )
    {
        if ( is_array( $what ) )
        {
            $output = array();
            for ( $i = 0; $i < count( $what ); $i++ )
                $what[ $i ] = $dbConn->quoteSmart( $what[ $i ] );           
            for ( $offset = 0; $offset < count( $what ); $offset += 1000 ) // avoid too large queries
                $output[] = 'fsPath IN (' . join( ',', array_slice( $what, $offset, 1000 ) ) . ')';
            return $output;
        }
        else {
            return array( AxDB::getDirectDescendantsCondition( $dbConn, $what ) );
        }       
    }

    /**
     * Returns filename component of path
     * Works with multi-byte characters 
     *
     * @param string $path A path
     * @return string the base name of the given path
     */
    public static function getBasename( $path )
    {
		$lastSlash = strrpos($path, '/');
		if ($lastSlash == FALSE)
			$result = $path;
		else
			$result = substr($path, $lastSlash + 1);
		return $result;
    }

    /**
     * Returns directory name of a path
     * Works with multi-byte characters
     *
     * @param string $path The path to retrieve the parent directory from
     * @param bool   $abs  TRUE to return "/" if there is no parent directory, FALSE to return ""
     * @return string The directory name of the specified path
     */
    public static function getDirname( $path, $abs=FALSE )
	{
		$lastSlash = strrpos($path, '/');
		if ($lastSlash == FALSE)
			$result = "";
		else
			$result = substr($path, 0, $lastSlash);
        return ($result == "" && $abs) ? "/" : $result;
    }


}
