<?php
namespace util\PHPExcel;

use Mall\Framework\Core\ResultWrapper;
use Mall\Framework\Core\ErrorCode;

/**
 * Created by PhpStorm.
 * User: phperstar
 * Date: 2020/8/10
 * Time: 3:32 PM
 */
class IOFactory
{
    /**
     * Search locations
     *
     * @var    array
     * @access    private
     * @static
     */
    private static $searchLocations = array(
        array( 'type' => 'IWriter', 'path' => '\Util\PHPExcel\Writer\{0}', 'class' => '{0}' ),
        array( 'type' => 'IReader', 'path' => '\Util\PHPExcel\Reader\{0}', 'class' => '{0}' )
    );

    /**
     * Loads PHPExcel from file using automatic PHPExcel_Reader_IReader resolution
     *
     * @static
     * @access public
     * @param     string         $pFilename        The name of the spreadsheet file
     * @return    ResultWrapper
     * @throws    PHPExcel_Reader_Exception
     */
    public static function load($pFilename)
    {
        $result = self::createReaderForFile($pFilename);
        if(!$result->isSuccess()){
            return ResultWrapper::fail($result->getData(), $result->getErrorCode());
        }

        $reader = $result->getData();
        $reader->setReadDataOnly(true); // 只读取数据
        return ResultWrapper::success($reader->load($pFilename));
    }

    /**
     * Create PHPExcel_Reader_IReader for file using automatic PHPExcel_Reader_IReader resolution
     *
     * @static
     * @access    public
     * @param     string         $pFilename        The name of the spreadsheet file
     * @return    ResultWrapper
     */
    public static function createReaderForFile($pFilename)
    {
        $pathinfo = pathinfo($pFilename);

        $extensionType = null;
        if (isset($pathinfo['extension'])) {
            switch (strtolower($pathinfo['extension'])) {
                case 'xlsx':            //    Excel (OfficeOpenXML) Spreadsheet
                case 'xlsm':            //    Excel (OfficeOpenXML) Macro Spreadsheet (macros will be discarded)
                case 'xltx':            //    Excel (OfficeOpenXML) Template
                case 'xltm':            //    Excel (OfficeOpenXML) Macro Template (macros will be discarded)
                    $extensionType = 'Excel2007';
                    break;
                case 'xls':                //    Excel (BIFF) Spreadsheet
                case 'xlt':                //    Excel (BIFF) Template
                    $extensionType = 'Excel5';
                    break;
                case 'ods':                //    Open/Libre Offic Calc
                case 'ots':                //    Open/Libre Offic Calc Template
                    $extensionType = 'OOCalc';
                    break;
                case 'slk':
                    $extensionType = 'SYLK';
                    break;
                case 'xml':                //    Excel 2003 SpreadSheetML
                    $extensionType = 'Excel2003XML';
                    break;
                case 'gnumeric':
                    $extensionType = 'Gnumeric';
                    break;
                case 'htm':
                case 'html':
                    $extensionType = 'HTML';
                    break;
                case 'csv':
                    // Do nothing
                    // We must not try to use CSV reader since it loads
                    // all files including Excel files etc.
                    break;
                default:
                    break;
            }

            if ($extensionType !== null) {
                $result = self::createReader($extensionType);
                if(!$result->isSuccess()){
                    return ResultWrapper::fail($result->getData(), $result->getErrorCode());
                }

                $reader = $result->getData();
                if (isset($reader) && $reader->canRead($pFilename)) {
                    return ResultWrapper::success($reader);
                }
            }
        }

        // If we reach here then "lucky guess" didn't give any result
        // Try walking through all the options in self::$autoResolveClasses
        /*foreach (self::$autoResolveClasses as $autoResolveClass) {
            //    Ignore our original guess, we know that won't work
            if ($autoResolveClass !== $extensionType) {
                $reader = self::createReader($autoResolveClass);
                if ($reader->canRead($pFilename)) {
                    return $reader;
                }
            }
        }*/

        return ResultWrapper::fail('当前文件类型无法读取', ErrorCode::$notAllowAccess);
    }

    /**
     * Create PHPExcel_Reader_IReader
     *
     * @static
     * @access    public
     * @param    string $readerType    Example: Excel2007
     * @return    ResultWrapper
     */
    public static function createReader($readerType = '')
    {
        // Search type
        $searchType = 'IReader';

        // Include class
        foreach (self::$searchLocations as $searchLocation) {
            if ($searchLocation['type'] == $searchType) {
                $className = str_replace('{0}', $readerType, $searchLocation['path']);

                $instance = new $className();
                if ($instance !== null) {
                    return ResultWrapper::success($instance);
                }
            }
        }

        return ResultWrapper::fail('没有对应的解析解析类', ErrorCode::$notAllowAccess);
    }
}