<?php

namespace Box\Spout\Common\Helper;

/**
 * Class GlobalFunctionsHelper
 * This class wraps global functions to facilitate testing
 *
 * @codeCoverageIgnore
 */
class GlobalFunctionsHelper
{
    /**
     * Wrapper around global function fopen()
     * @see fopen()
     *
     * @param string $fileName
     * @param string $mode
     * @return resource|bool
     */
    public function fopen($fileName, $mode)
    {
        return \fopen($fileName, $mode);
    }

    /**
     * Wrapper around global function fgets()
     * @see fgets()
     *
     * @param resource $handle
     * @param int|null $length
     * @return string
     */
    public function fgets($handle, $length = null)
    {
        return \fgets($handle, $length);
    }

    /**
     * Wrapper around global function fputs()
     * @see fputs()
     *
     * @param resource $handle
     * @param string $string
     * @return int
     */
    public function fputs($handle, $string)
    {
        return \fputs($handle, $string);
    }

    /**
     * Wrapper around global function fflush()
     * @see fflush()
     *
     * @param resource $handle
     * @return bool
     */
    public function fflush($handle)
    {
        return \fflush($handle);
    }

    /**
     * Wrapper around global function fseek()
     * @see fseek()
     *
     * @param resource $handle
     * @param int $offset
     * @return int
     */
    public function fseek($handle, $offset)
    {
        return \fseek($handle, $offset);
    }

    /**
     * Wrapper around global function fgetcsv()
     * @see fgetcsv()
     *
     * @param resource $handle
     * @param int|null $length
     * @param string|null $delimiter
     * @param string|null $enclosure
     * @return array
     */
    public function fgetcsv($handle, $length = null, $delimiter = null, $enclosure = null)
    {
        $escapeCharacter = PHP_VERSION_ID >= 70400 ? '' : "\0";

        return \fgetcsv($handle, $length, $delimiter, $enclosure, $escapeCharacter);
    }

    /**
     * Wrapper around global function fputcsv()
     * @see fputcsv()
     *
     * @param resource $handle
     * @param array $fields
     * @param string|null $delimiter
     * @param string|null $enclosure
     * @return int
     */
    public function fputcsv($handle, array $fields, $delimiter = null, $enclosure = null)
    {
        $escapeCharacter = PHP_VERSION_ID >= 70400 ? '' : "\0";

        return \fputcsv($handle, $fields, $delimiter, $enclosure, $escapeCharacter);
    }

    /**
     * Wrapper around global function fwrite()
     * @see fwrite()
     *
     * @param resource $handle
     * @param string $string
     * @return int
     */
    public function fwrite($handle, $string)
    {
        return \fwrite($handle, $string);
    }

    /**
     * Wrapper around global function fclose()
     * @see fclose()
     *
     * @param resource $handle
     * @return bool
     */
    public function fclose($handle)
    {
        return \fclose($handle);
    }

    /**
     * Wrapper around global function rewind()
     * @see rewind()
     *
     * @param resource $handle
     * @return bool
     */
    public function rewind($handle)
    {
        return \rewind($handle);
    }

    /**
     * Wrapper around global function file_exists()
     * @see file_exists()
     *
     * @param string $fileName
     * @return bool
     */
    public function file_exists($fileName)
    {
        return \file_exists($fileName);
    }

    /**
     * Wrapper around global function file_get_contents()
     * @see file_get_contents()
     *
     * @param string $filePath
     * @return string
     */
    public function file_get_contents($filePath)
    {
        $realFilePath = $this->convertToUseRealPath($filePath);

        return \file_get_contents($realFilePath);
    }

    /**
     * Updates the given file path to use a real path.
     * This is to avoid issues on some Windows setup.
     *
     * @param string $filePath File path
     * @return string The file path using a real path
     */
    protected function convertToUseRealPath($filePath)
    {
        $realFilePath = $filePath;

        if ($this->isZipStream($filePath)) {
            if (\preg_match('/zip:\/\/(.*)#(.*)/', $filePath, $matches)) {
                $documentPath = $matches[1];
                $documentInsideZipPath = $matches[2];
                $realFilePath = 'zip://' . \realpath($documentPath) . '#' . $documentInsideZipPath;
            }
        } else {
            $realFilePath = \realpath($filePath);
        }

        return $realFilePath;
    }

    /**
     * Returns whether the given path is a zip stream.
     *
     * @param string $path Path pointing to a document
     * @return bool TRUE if path is a zip stream, FALSE otherwise
     */
    protected function isZipStream($path)
    {
        return (\strpos($path, 'zip://') === 0);
    }

    /**
     * Wrapper around global function feof()
     * @see feof()
     *
     * @param resource $handle
     * @return bool
     */
    public function feof($handle)
    {
        return \feof($handle);
    }

    /**
     * Wrapper around global function is_readable()
     * @see is_readable()
     *
     * @param string $fileName
     * @return bool
     */
    public function is_readable($fileName)
    {
        return \is_readable($fileName);
    }

    /**
     * Wrapper around global function basename()
     * @see basename()
     *
     * @param string $path
     * @param string|null $suffix
     * @return string
     */
    public function basename($path, $suffix = null)
    {
        return \basename($path, $suffix);
    }

    /**
     * Wrapper around global function header()
     * @see header()
     *
     * @param string $string
     * @return void
     */
    public function header($string)
    {
        \header($string);
    }

    /**
     * Wrapper around global function ob_end_clean()
     * @see ob_end_clean()
     *
     * @return void
     */
    public function ob_end_clean()
    {
        if (\ob_get_length() > 0) {
            \ob_end_clean();
        }
    }

    /**
     * Wrapper around global function iconv()
     * @see iconv()
     *
     * @param string $string The string to be converted
     * @param string $sourceEncoding The encoding of the source string
     * @param string $targetEncoding The encoding the source string should be converted to
     * @return string|bool the converted string or FALSE on failure.
     */
    public function iconv($string, $sourceEncoding, $targetEncoding)
    {
        return \iconv($sourceEncoding, $targetEncoding, $string);
    }

    /**
     * Wrapper around global function mb_convert_encoding()
     * @see mb_convert_encoding()
     *
     * @param string $string The string to be converted
     * @param string $sourceEncoding The encoding of the source string
     * @param string $targetEncoding The encoding the source string should be converted to
     * @return string|bool the converted string or FALSE on failure.
     */
    public function mb_convert_encoding($string, $sourceEncoding, $targetEncoding)
    {
        return \mb_convert_encoding($string, $targetEncoding, $sourceEncoding);
    }

    /**
     * Wrapper around global function stream_get_wrappers()
     * @see stream_get_wrappers()
     *
     * @return array
     */
    public function stream_get_wrappers()
    {
        return \stream_get_wrappers();
    }

    /**
     * Wrapper around global function function_exists()
     * @see function_exists()
     *
     * @param string $functionName
     * @return bool
     */
    public function function_exists($functionName)
    {
        return \function_exists($functionName);
    }
}
