<?php
declare (strict_types = 1);

namespace app\command;
use Exception;
use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\input\Option;
use think\console\Output;

use think\facade\Cache;

use Curl\Curl;
use think\helper\Str;
use app\kernel\Lebolebo\Account;
use app\kernel\Lebolebo\Curriculum;

use Aria2;

class Lebo extends Command
{
    private $aria2 = null;
    private $completed = false;

    protected function configure()
    {
        // 指令配置
        $this->setName('course')
            ->setDescription('the course command');
    }
    protected function execute(Input $input, Output $output)
    {
        $this->aria2 = new Aria2('http://127.0.0.1:16800/jsonrpc','11223344'); 
        $this->completed = false;
        while($this->completed === false){
            try {
                $this->start();
            } catch (\Exception $e) {
                dump($e);
                sleep(3);
            }
        }
        dump('下载完成！');
        // 指令输出
        // $output->writeln('course');
    }
    private function start()
    {
        // $savepath = store_path() . '/lebolebo/';
        $savepath = 'E:/lebolebo/';
        $account = new Account();
        $account_info = $account->login('13880615958','robo520');
        if($account_info['code'] == 500){
            dump($account_info['msg']);
            exit;
        }
        $curl = new Curl();
        $curr = new Curriculum();
        $curr->setHeader('token',$account_info['data']['token']);
        $course = $curr->list(0);

        foreach ($course['data']['list'] as $list){
            $c = $savepath . $list['courseName'];
            is_dir($c) || mkdir($c,0755,true);
            $detail = $curr->detail($list['id']);
            $courseCover = $c . '/courseCover.png';
            if($detail['data']['courseCover']){
                $downloadurl = $detail['data']['courseCover'];
                $check = $this->checkfile($downloadurl,$courseCover);
                if(!$check && !is_file($courseCover)){
                    // $result = $curl->_fastDownload($downloadurl,$courseCover);
                    $this->aria2->addUri(
                        [$downloadurl],
                        ['dir'=>$c,
                        'out'=>'courseCover.png'
                        ]
                    );
                    // dump('封面下载结果：',$result);
                    // if($result){
                    //     $this->complete($downloadurl,$courseCover);
                    // }
                }
                $txt = $courseCover . '-下载地址.txt';
                $this->savetxt($txt,$downloadurl);
            }
            $d = $curr->courseUnitList($list['courseCode']);
            $courseUnits = $d['data']['courseUnit'];
            if($courseUnits === null){
                continue;
            }
            foreach ($courseUnits as $courseUnit){
                $courseUnitName = $c . '/' . str_ireplace('/','-',$courseUnit['courseUnitName']);
                if(!is_dir($courseUnitName)){
                    dump('创建课程文件夹：' . $courseUnitName);
                    mkdir($courseUnitName,0755,true);
                }
                $selectByCourseUnits = $curr->selectByCourseUnits($courseUnit['courseCode'],$courseUnit['courseUnitCode']);
                foreach ($selectByCourseUnits['data'] as $selectByCourseUnit){
                    $this->waiting();
                    $sessionName = $courseUnitName . '/' . $selectByCourseUnit['sessionName'];
                    if(!is_dir($sessionName)){
                        dump('创建课件文件夹：'.$sessionName);
                        mkdir($sessionName,0755,true);
                    }
                    $t = $curr->selectByCourseSessionCode($selectByCourseUnit['courseSessionCode']);
                    // 0: {type: 1, des: "PPT-HTML"}
                    // 1: {type: 2, des: "讲义"}
                    // 2: {type: 3, des: "课前预习"}
                    // 3: {type: 4, des: "测一测"}
                    // 4: {type: 5, des: "玩一玩"}
                    // 5: {type: 6, des: "试一试"}
                    // 6: {type: 9, des: "知识点"}
                    // 7: {type: 10, des: "名人名言"}
                    // 8: {type: 11, des: "录播课"}
                    // 9: {type: 13, des: "教辅"}
                    // 10: {type: 14, des: "备课"}
                    // 11: {type: 15, des: "课程内容"}
                    // 12: {type: 16, des: "课后拓展"}
                    // 13: {type: 18, des: "素养目标"}
                    $ts = $t['data'];
                    foreach ($ts as $kk ){
                        switch ($kk['resourceType']) {
                            case '1':// PPT-HTML
                                if(!isset($kk['content'])){
                                    continue;
                                }
                                $filename = $kk['content']['fileName'];
                                $downloadurl = $kk['content']['fileUrl'];
                                $file = $sessionName . '/' . $filename;
                                // 保存下载地址
                                $txt = "{$file}-下载地址.txt";
                                $this->savetxt($txt,$downloadurl);
                                $check = $this->checkfile($downloadurl,$file);
                                if(!$check && !is_file($file)){
                                    dump('下载PPT：' . $file);
                                    // $result = $curl->_fastDownload($downloadurl,$file);
                                    // dump('PPT下载结果：',$result);
                                    // if($result){
                                    //     $this->complete($downloadurl,$file);
                                    // }
                                    $this->aria2->addUri(
                                        [$downloadurl],
                                        ['dir'=>$sessionName,
                                        'out'=>$filename]
                                    );
                                }else if($check && !is_file($file)){
                                    if(is_file($check)){
                                        try {
                                            copy($check,$file);
                                        } catch (Exception $e) {
                                            dump('文件拷贝失败：',$e);
                                            exit;
                                        }
                                    }else{
                                        dump('下载PPT：' . $file);
                                        // $result = $curl->_fastDownload($downloadurl,$file);
                                        // dump('PPT下载结果：',$result);
                                        // if($result){
                                        //     $this->complete($downloadurl,$file);
                                        // }
                                        $this->aria2->addUri(
                                            [$downloadurl],
                                            ['dir'=>$sessionName,
                                            'out'=>$filename]
                                        );
                                    }
                                    
                                    dump('跳过PPT：' . $file);
                                }else{
                                    dump('PPT文件已存在：' . $file);
                                    $this->complete($downloadurl,$file);
                                }
                                break;
                            case '2':
                                break;
                            case '3':
                                break;
                            case '4':
                                break;
                            case '5':
                                break;
                            case '6':
                                // 试一试
                                $shiyishi = $sessionName . '/试一试/';
                                if(!is_dir($shiyishi)){
                                    mkdir($shiyishi,0755,true);
                                }
                                $questions = $kk['content']['questions'];
                                if(!is_array($questions))break;
                                foreach ($questions as $key => $question) {
                                    $filename = $question['fileName'];
                                    $downloadurl = $question['fileUrl'];
                                    $file = $shiyishi . $filename;
                                    // 保存文件下载地址
                                    $txt = "{$file}-下载地址.txt";
                                    $this->savetxt($txt,$downloadurl);
                                    $check = $this->checkfile($downloadurl,$file);
                                    if(!$check && !is_file($file)){
                                        // $result = $curl->_fastDownload($downloadurl,$file);
                                        // dump('试一试下载结果：',$result);
                                        // if($result){
                                        //     $this->complete($downloadurl,$file);
                                        // }
                                        $this->aria2->addUri(
                                            [$downloadurl],
                                            ['dir'=>$shiyishi,
                                            'out'=>$filename]
                                        );
                                    }else if($check && !is_file($file)){
                                        copy($check,$file);
                                        dump('跳过试一试：' . $file);
                                    }else{
                                        dump('试一试文件已存在：' . $file);
                                        $this->complete($downloadurl,$file);
                                    }
                                }
                                break;
                            case '9':
                                break;
                            case '10':
                                break;
                            case '11':
                                break;
                            case '13':
                                // 教辅
                                if(!isset($kk['content']['resourceList'])){
                                    continue;
                                }
                                $jiaofupath = $sessionName . '/教辅/';
                                if(!is_dir($jiaofupath)){
                                    mkdir($jiaofupath,0755,true);
                                }
                                $resourceLists = $kk['content']['resourceList'];
                                foreach($resourceLists as $resourceList){
                                    $file = $jiaofupath . $resourceList['fileName'] ;
                                    if(Str::endsWith($file,['.mp4','.mov'])){
                                        $dd = $curr->getVideoUrl($resourceList['fileUrl']);
                                        $downloadurl = $dd['data'];
                                    }else{
                                        $downloadurl = $resourceList['fileUrl'];
                                    }
                                    // 保存下载地址
                                    $txt = "{$file}-下载地址.txt";
                                    $this->savetxt($txt,$downloadurl);
                                    $check = $this->checkfile($downloadurl,$file);
                                    if(!$check && !is_file($file)){
                                        dump('下载教辅：' . $file);
                                        // $result = $curl->_fastDownload($downloadurl,$file);
                                        // dump('教辅下载结果：',$result);
                                        // if($result){
                                        //     $this->complete($downloadurl,$file);
                                        // }
                                        $this->aria2->addUri(
                                            [$downloadurl],
                                            ['dir'=>$jiaofupath,
                                            'out'=>$resourceList['fileName']]
                                        );
                                    }else if($check && !is_file($file)){
                                        copy($check,$file);
                                        dump('跳过教辅：' . $file);
                                    }else{
                                        dump('教辅文件已存在：' . $file);
                                        $this->complete($downloadurl,$file);
                                    }
                                }
                                break;
                            case '14':
                                // 备课
                                if(!isset($kk['content']['resourceList'])){
                                    continue;
                                }
                                $beikepath = $sessionName . '/备课/';
                                if(!is_dir($beikepath)){
                                    mkdir($beikepath,0755,true);
                                }
                                $resourceLists = $kk['content']['resourceList'];
                                foreach($resourceLists as $resourceList){
                                    $file = $beikepath . $resourceList['fileName'] ;
                                    if(Str::endsWith($file,['.mp4','.mov','.MP4','.mkv','.wmv'])){
                                        $dd = $curr->getVideoUrl($resourceList['fileUrl']);
                                        $downloadurl = $dd['data'];
                                    }else{
                                        $downloadurl = $resourceList['fileUrl'];
                                    }
                                    // 保存下载地址
                                    $txt = "{$file}-下载地址.txt";
                                    $this->savetxt($txt,$downloadurl);
                                    $check = $this->checkfile($downloadurl,$file);
                                    if(!$check && !is_file($file)){
                                        dump('下载备课：' . $file);
                                        // $result = $curl->_fastDownload($downloadurl,$file);
                                        // dump('备课下载结果：',$result);
                                        // if($result){
                                        //     $this->complete($downloadurl,$file);
                                        // }
                                        $this->aria2->addUri(
                                            [$downloadurl],
                                            ['dir'=>$beikepath,
                                            'out'=>$resourceList['fileName']]
                                        );
                                    }else if($check && !is_file($file)){
                                        copy($check,$file);
                                        dump('跳过备课：' . $file);
                                    }else{
                                        dump('备课文件已存在：' . $file);
                                        $this->complete($downloadurl,$file);
                                    }
                                }
                                break;
                            case '15':
                                // 课程内容
                                if(is_null($kk['content']['courseContent']))break;
                                $file = "{$sessionName}/课程内容.txt";
                                $this->savetxt($file,strip_tags($kk['content']['courseContent']));
                                break;
                            case '16':
                                break;
                            case '18':
                                break;
                            default:
                                break;
                        }
                        // break;
                    }
                }
            }
            // break;
        }
        $this->completed = true;
    }
    private function checkfile($url,$file)
    {
        $key = 'lebolebo_check_header_'.md5($url);
        try {
            if(($head = Cache::get($key,null)) === NULL ){
                $head = @get_headers($url,1);
                if ($head === false) {
                    dump('获取文件信息失败，直接重新下载'.$file);
                    return false;
                }
                Cache::set($key,$head,86400);
            }
            $kk = 'lebolebo_file_' . pathinfo($file,PATHINFO_BASENAME);
            if(isset($head['Content-Length']) && ($size = intval($head['Content-Length']))){
                $kk .= $size;
                if(is_file($file) && ($size !== filesize($file))){
                    dump('文件大小不符，重新下载'.$file);
                    unlink($file);
                    return false;
                }
            }
            if(isset($head['ETag'])){
                $t = $kk . md5($head['ETag']);
                if(Cache::has($t)){
                    return Cache::get($t);
                }
            }
            if(isset($head['Content-MD5'])){
                $t = $kk . md5($head['Content-MD5']);
                if(Cache::has($t)){
                    return Cache::get($t);
                }
            }
        } catch (Exception $e) {
            dump('检查文件失败：',$url,$file,$e);
            exit;
        }
        return false;
    }
    private function complete($url,$file)
    {
        $key = 'lebolebo_check_header_' . md5($url);
        try {
            if(($head = Cache::get($key,null)) === NULL ){
                $head = @get_headers($url,1);
                if($head === false){
                    return false;
                }
                Cache::set($key,$head,86400);
            }
            $kk = 'lebolebo_file_' . pathinfo($file,PATHINFO_BASENAME);
            if(isset($head['Content-Length'])){
                $kk .= intval($head['Content-Length']);
            }
            if(isset($head['ETag'])){
                $t = $kk . md5($head['ETag']);
                Cache::set($t,$file,86400);
            }
            if(isset($head['Content-MD5'])){
                $t = $kk . md5($head['Content-MD5']);
                Cache::set($t,$file,86400);
            }
        } catch (Exception $e) {
            dump($e);
            exit;
        }
    }
    private function savetxt(string $file,string $content)
    {
        if(is_file($file)){
            unlink($file);
        }
        $myfile = fopen($file, "w");
        fwrite($myfile, $content);
        fclose($myfile);
        // dump('已保存文本内容：'.$file);
    }
    private function waiting()
    {
        $num = 1;
        while($num > 0){
            $activeDownloads = $this->aria2->getGlobalStat();
            $num = intval($activeDownloads['result']['numWaiting']);
            if($num > 10){
                dump('当前任务过多，等待任务数：',$num);
                sleep(1);
            }else{
                break;
            }
        }
    }
}
