#!/usr/bin/php
<?php 
namespace Convoworks;

use Convoworks\wapmorgan\Mp3Info\Mp3Info;
$paths = [
    // as a root package or phar
    __DIR__ . '/../vendor/autoload.php',
    // as a dependency from bin
    __DIR__ . '/../autoload.php',
    // as a dependency from package folder
    __DIR__ . '/../../../autoload.php',
];
function init_composer(array $paths)
{
    foreach ($paths as $path) {
        if (\file_exists($path)) {
            require_once $path;
            return \true;
        }
    }
    return \false;
}
if (!init_composer($paths)) {
    die('Run `composer install` firstly.' . \PHP_EOL);
}
if ($argc == 1) {
    die('Specify file names to scan');
}
class Mp3InfoConsoleRunner
{
    /** @var array */
    protected $widths = array('filename' => 0.3, 'duration' => 6, 'bitRate' => 6, 'sampleRate' => 6, 'song' => 0.13, 'artist' => 0.125, 'track' => 5, 'parseTime' => 4);
    /** @var string */
    protected $songRowTempalte;
    /** @var bool */
    protected $compareWithId3;
    protected $totalDuration = 0;
    protected $totalParseTime = 0;
    protected $totalId3ParseTime = 0;
    /**
     * @param array $fileNames
     * @param bool  $verbose
     */
    public function run(array $fileNames, $verbose = \false)
    {
        $this->adjustOutputSize();
        $this->songRowTempalte = '%' . $this->widths['filename'] . 's | %' . $this->widths['duration'] . 's | %' . $this->widths['bitRate'] . 's | %' . $this->widths['sampleRate'] . 's | %' . $this->widths['song'] . 's | %' . $this->widths['artist'] . 's | %' . $this->widths['track'] . 's | %' . $this->widths['parseTime'] . 's';
        $this->compareWithId3 = \class_exists('Convoworks\\getID3');
        echo \sprintf($this->songRowTempalte, 'File name', 'dur.', 'bitrate', 'sample', 'song', 'artist', 'track', 'time') . \PHP_EOL;
        foreach ($fileNames as $originalFile) {
            $file = \realpath($originalFile);
            if (\is_dir($file)) {
                echo $file . ':' . \PHP_EOL;
                foreach (\glob(\rtrim($file, \DIRECTORY_SEPARATOR) . \DIRECTORY_SEPARATOR . '*.mp3') as $f) {
                    if (\is_file($f)) {
                        $this->analyze($f, \false, $verbose);
                        if ($this->compareWithId3) {
                            $this->analyzeId3($f);
                        }
                    }
                }
            } else {
                if (\is_file($file)) {
                    $this->analyze($file, \true, $verbose);
                    if ($this->compareWithId3) {
                        $this->analyzeId3($file);
                    }
                } else {
                    if (\strpos($originalFile, '://') !== \false) {
                        $this->analyze($originalFile, \true, $verbose);
                    }
                }
            }
        }
        echo \sprintf('%42s | %34s', 'Total duration: ' . self::formatTime($this->totalDuration), 'Total parsing time: ' . \round($this->totalParseTime, 5)) . \PHP_EOL;
        if ($this->compareWithId3) {
            echo \sprintf('%79s', 'Total getId3 parsing time: ' . \round($this->totalId3ParseTime, 5)) . \PHP_EOL;
        }
    }
    /**
     * @param $time
     *
     * @return string
     */
    public static function formatTime($time)
    {
        if ($time > 3600) {
            return \floor($time / 3600) . ':' . \str_pad(\floor($time % 3600 / 60), 2, 0, \STR_PAD_LEFT) . ':' . \str_pad($time % 60, 2, 0, \STR_PAD_LEFT);
        } else {
            return \floor($time / 60) . ':' . \str_pad($time % 60, 2, 0, \STR_PAD_LEFT);
        }
    }
    /**
     * @param $string
     * @param $maxLength
     *
     * @return string
     */
    public static function substrIfLonger($string, $maxLength)
    {
        if (\mb_strlen($string) > $maxLength) {
            return \mb_substr($string, 0, $maxLength - 3) . '...';
        }
        return $string;
    }
    /**
     *
     */
    protected function adjustOutputSize()
    {
        $terminal_width = \Convoworks\wapmorgan\TerminalInfo\TerminalInfo::getWidth();
        foreach ($this->widths as $element => $width) {
            if ($width >= 1) {
                continue;
            }
            $this->widths[$element] = \ceil($width * $terminal_width);
        }
    }
    /**
     * @param      $filename
     * @param bool $id3v2
     *
     * @param bool $verbose
     *
     * @return null|void
     */
    protected function analyze($filename, $id3v2 = \false, $verbose = \false)
    {
        if (!\is_readable($filename) && \strpos($filename, '://') === \false) {
            return;
        }
        try {
            $audio = new Mp3Info($filename, \true);
        } catch (\Exception $e) {
            echo "Exception when parsing " . $filename . ': ' . $e->getMessage() . \PHP_EOL;
            return null;
        }
        echo \sprintf($this->songRowTempalte, self::convertToNativeEncoding(self::substrIfLonger(\basename($filename), $this->widths['filename'])), self::formatTime($audio->duration), $audio->isVbr ? 'vbr' : $audio->bitRate / 1000 . 'kbps', $audio->sampleRate / 1000, isset($audio->tags['song']) ? self::substrIfLonger($audio->tags['song'], 11) : null, isset($audio->tags['artist']) ? self::substrIfLonger($audio->tags['artist'], 10) : null, isset($audio->tags['track']) ? self::substrIfLonger($audio->tags['track'], 5) : null, $audio->_parsingTime) . \PHP_EOL;
        if ($id3v2 && !empty($audio->tags2)) {
            foreach ($audio->tags as $tag => $value) {
                echo '    ' . $tag . ': ';
                echo self::convertToNativeEncoding($value) . \PHP_EOL;
            }
        }
        if ($verbose) {
            \print_r(\array_intersect_key(\get_object_vars($audio), \array_flip(['codecVersion', 'layerVersion', 'duration', 'bitRate', 'sampleRate', 'isVbr', 'hasCover', 'channel', 'tags', 'tags1', 'tags2', 'id3v2MajorVersion', 'id3v2MinorVersion'])));
        }
        $this->totalDuration += $audio->duration;
        $this->totalParseTime += $audio->_parsingTime;
    }
    /**
     * @param $filename
     */
    protected function analyzeId3($filename)
    {
        static $ID3;
        if ($ID3 === null) {
            $ID3 = new getID3();
        }
        $t = \microtime(\true);
        $info = $ID3->analyze($filename);
        $parse_time = \microtime(\true) - $t;
        echo \sprintf($this->songRowTempalte, self::substrIfLonger(\basename($filename), $this->widths['filename']), $info['playtime_string'], $info['audio']['bitrate_mode'] == 'vbr' ? 'vbr' : \floor($info['audio']['bitrate'] / 1000) . 'kbps', $info['audio']['sample_rate'] / 1000, isset($info['tags']['title']) ? self::substrIfLonger($info['tags']['title'], 11) : null, isset($info['tags']['artist']) ? self::substrIfLonger($info['tags']['artist'], 10) : null, null, $parse_time) . \PHP_EOL;
        $this->totalId3ParseTime += $parse_time;
    }
    protected static function convertToNativeEncoding($string)
    {
        //        if (strncasecmp(PHP_OS, 'win', 3) === 0)
        //            return mb_convert_encoding($string, 'cp1251', 'utf-8');
        return $string;
    }
}
\class_alias('Convoworks\\Mp3InfoConsoleRunner', 'Mp3InfoConsoleRunner', \false);
\array_shift($argv);
$verbose = \false;
if (\in_array('-v', $argv, \true)) {
    $verbose = \true;
    unset($argv[\array_search('-v', $argv, \true)]);
}
$runner = new Mp3InfoConsoleRunner();
$runner->run($argv, $verbose);
