<?php

    namespace App\System\Vendor;
    use App\System\Controller\ConnectionController;
    use ZipArchive;

    class beUpdate {
        public static function beDownloadUpdate(){
            $data = self::beCheckUpdate();
            if(!$data["status"]){
                return ["status" => false,"message" => $data["message"]];
            }
            if(!$data["process"]){
                return ["status" => false,"message" => $data["message"]];
            }
            $update = $data["update"];
            if($update["ustatus"] != 2){
                return ["status" => false,"message" => "Güncelleme şuan için hazır değil!"];
            }
            $file = $update["ufile"];
            $response = self::beApplyUpgrade($file);
            if(!$response["status"]){
                return ["status" => false,"message" => $response["message"]];
            }
            $mainfile = BE_ROOT."app/resources/cache/version.json";
            $system = file_get_contents($mainfile);
            $system = json_decode($system,true);
            $system["build"] = $update["ubuild"];
            $system["version"] = $update["uversion"];
            file_put_contents($mainfile,json_encode($system,JSON_UNESCAPED_UNICODE));
            return ["status" => true,"message" => "Başarılı bir şekilde güncelleme yapıldı","system" => $system];
        }
        public static function beApplyUpgrade($file = "",$type = "updates"){
            $apiUrl = ConnectionController::beGetActiveApi();
            $uploaddir = BE_ROOT."app/resources/update/";
            $filesdir = $uploaddir."temp/";
            $mainfilesdir = $uploaddir."temp";
            $zipdir = $uploaddir.$file;
            $data = file_get_contents($apiUrl."/".$type."/".$file,false,stream_context_create([
                "ssl" => [
                    "verify_peer" => false,
                    "verify_peer_name" => false
                ]
            ]));
            if(!$data){
                return ["status" => false,"message" => "Güncelleme ile ilgili bir sorun oluştu lütfen yönetici ile iletişime geçin. Hata Kodu 0xD1","code" => 1];
            }
            if(!file_put_contents($zipdir,$data)){
                return ["status" => false,"message" => "Güncelleme ile ilgili bir sorun oluştu lütfen yönetici ile iletişime geçin. Hata Kodu 0xD2","code" => 2];
            }
            $zip = new ZipArchive();
            $status = $zip->open($zipdir);
            if($status !== true){
                return ["status" => false,"message" => "Güncelleme yapılırken rar dosyası açılamadı!","code" => 3];
            }
            $success = $zip->extractTo($filesdir);
            $zip->close();
            if($success === false){
                return ["status" => false,"message" => "Güncelleme yapılırken rar dışarı çıkarılamadı!","code" => 4];
            }
            unlink($zipdir);
            $response = self::beMoveZipFiles($mainfilesdir,$mainfilesdir);
            if(!$response["status"]){
                return ["status" => false,"message" => $response["message"]];
            }
            $execfile = BE_ROOT."exec.data";
            if(file_exists($execfile)){
                $data = file_get_contents($execfile);
                eval($data);
                unlink($execfile);
            }
            self::beClearDirectory($filesdir);
            return ["status" => true,"message" => "Başarılı bir şekilde güncelleme uygulandı!"];
        }
        public static function beCheckUpdate(){
            global $be;
            $settings = $be->settings;
            $mainfile = BE_ROOT."app/resources/cache/version.json";
            if(file_exists($mainfile)){
                $system = file_get_contents($mainfile);
                $system = json_decode($system,true);
                $build = $system["build"] ?? 0;
                $response = ConnectionController::beSendRequestUpdate([
                    "method" => "checkupdate",
                    "data" => [
                        "build" => $build,
                        "cid" => $settings["system_id"],
                        "ctoken" => $settings["system_token"],
                        "secret" => $settings["system_secret"]
                    ]
                ]);
                return $response;
            }
        }
        public static function beMoveZipFiles($dir = "",$mainfilesdir = ""){
            foreach(glob($dir."/*") as $file){
                if(is_dir($file)){
                    self::beMoveZipFiles($file,$mainfilesdir);
                }
                else{
                    $putfile = str_replace($mainfilesdir."/","",$file); 
                    $path = explode("/",$putfile);
                    $length = count($path)-1;
                    for($i = 0; $i < $length; $i++){
                        $checkpath = "";
                        if($i > 0){
                            for($j = 0; $j < $i; $j++){
                                $checkpath .= $path[$j]."/";
                            }
                        }
                        $checkpath .= $path[$i];
                        if(!file_exists(BE_ROOT.$checkpath)){
                            if(!mkdir(BE_ROOT.$checkpath)){
                                return ["status" => false,"message" => "Güncelleme dosyası yazılırken bir sorun oluştu, dosya izinlerini kontrol edin. Hata Kodu 0xD4","code" => 6];
                            }
                        }
                    }
                    $data = file_get_contents($file);
                    chmod(BE_ROOT.$putfile,0777);
                    if(!file_put_contents(BE_ROOT.$putfile,$data)){
                        return ["status" => false,"message" => "Güncelleme ile ilgili bir sorun oluştu, dosya izinlerini kontrol edin. Hata Kodu 0xD5".$putfile,"code" => 7];
                    }
                    unlink($file);
                }
            }
            return ["status" => true];
        }
        public static function beClearDirectory($dir = ""){
            foreach(glob($dir."*") as $file){
                if(is_dir($file)){
                    self::beClearDirectory($file."/*");
                }
                else{
                    unlink($file);
                }
            }
            rmdir(substr($dir,0,-1));
            return ["status" => true];
        }
    }
?>