<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Http\Controllers\SuperAdminController;

//database migration
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

//Used for Form data validation
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
use ZipArchive, DB;
use Artisan;

class Updater extends Controller
{
    function update(Request $request){

		$addons_parent_id = null;

		//check required version
		$product_current_version = DB::table('global_settings')->where('key', 'version')->value('value');

        $rules = array('file' => 'required|file|mimes:zip');
        $validator = Validator::make($request->all(), $rules);
        if ($validator->fails()){
            return redirect()->back()->with('warning', get_phrase('Select a valid zip file'));
        }

        //Create update directory
        $dir = 'upload';
        if (!is_dir($dir)){
            mkdir($dir, 0777, true);
        }


        //Uploaded file name
        $file_name = $request->file->getClientOriginalName();
        $path = $dir.'/'.$file_name;


        if (class_exists('ZipArchive')) {
            //File uploading..
        	$request->file->move(base_path($dir), $request->file->getClientOriginalName());

            // Unzip uploaded update file and remove zip file.
            $zip = new ZipArchive;
            $res = $zip->open(base_path($path));
            $zip->extractTo(base_path($dir));
            $zip->close();
            unlink(base_path($path));
        }else{
            return redirect()->back()->with('warning', get_phrase('Your server is unable to extract the zip file').'. '.get_phrase('Please enable the zip extension to the server, then try again'));
        }

        $uploaded_folder_name = substr($file_name, 0, -4);
        $version_ = substr($file_name, 0, -4);
        
        // Exicute php or laravel's code
        if(file_exists(base_path($dir.'/'.$uploaded_folder_name.'/step1_pre_checker.php'))){
        	$step1Exicution = file_get_contents(base_path($dir.'/'.$uploaded_folder_name.'/step1_pre_checker.php'));
	        if($step1Exicution){
				eval($step1Exicution);
			}
        }


		$config = file_get_contents(base_path($dir.'/'.$uploaded_folder_name.'/step2_config.json'));
        if($config){
			$config = json_decode($config, true);
		}


		//check ias addon or main product update
		if(array_key_exists('is_addon', $config) && strval($config['is_addon']) == "1"){

			if(isset($request->purchase_code) && $request->purchase_code != ''){
				$response = (new SuperAdminController)->curl_request($request->purchase_code);
				
				if($response != 1) {
					return redirect()->back()->with('error', get_phrase('Purchase code verification failed'));
				} else{
					$duplicate_code_check = DB::table('addons')->where('purchase_code', $request->purchase_code)->get();
					if(count($duplicate_code_check) > 0){
						return redirect()->back()->with('error', get_phrase('You have already use this purchase code'));
					}
				}
				
			} else {
				return redirect()->back()->with('error', get_phrase('Purchase code verification failed'));
			}


			$pre_version = $product_current_version;
			if(str_contains($product_current_version, '.10')){
				$product_current_version = str_replace('.10', '.9.1', $product_current_version);
			}
			if(str_contains($product_current_version, '.10')){
				$product_current_version = str_replace('.20', '.19.1', $product_current_version);
			}

			//check required main product version to install this addon
			if($config['product_version']['minimum_required_version'] > $product_current_version){
				return redirect()->back()->with('warning', get_phrase("You have to update your main application's version.").'('.$config['product_version']['minimum_required_version'].') '.get_phrase(' to install the addon'));
			}
			$product_current_version = $pre_version;

			$addons_current_version = DB::table('addons')->where('unique_identifier', $config['addons'][0]['unique_identifier']);
			if($addons_current_version->get()->count() > 0){
				$addons_current_version = $addons_current_version->value('version');
			}else{
				$addons_current_version = $config['addon_version']['minimum_required_version'];
			}

			//check required addon version to update this addon
			if(strval($config['addon_version']['minimum_required_version']) > strval($addons_current_version)){
				return redirect()->back()->with('warning', get_phrase('It looks like you are skipping a version').'. '.get_phrase('Please update version').' '.$config['addon_version']['minimum_required_version'].' '.get_phrase('first'));
			}
			
			foreach($config['addons'] as $addon){
				$data['unique_identifier'] = $addon['unique_identifier'];
				$data['title'] = $addon['title'];
				$data['version'] = $config['addon_version']['update_version'];
				$data['features'] = $addon['features'];
				$data['status'] = 1;
				$data['parent_id'] = $addons_parent_id;

				$addons_details = DB::table('addons')->where('unique_identifier', $config['addons'][0]['unique_identifier']);

				if($addons_details->get()->count() > 0){
					DB::table('addons')->where('id', $addons_details->value('id'))->update($data);
					$parent_id = $addons_details->value('id');
				} else {
					$parent_id = DB::table('addons')->insertGetId($data);
				}


				if($addons_parent_id == null){
					$addons_parent_id = $parent_id;
				}
			}

			
		}else{
			//check required main product version
			if(strval($config['product_version']['minimum_required_version']) != strval($product_current_version)){
				return redirect()->back()->with('warning', get_phrase('It looks like you are skipping a version').'. '.get_phrase('Please update version').' '.$config['product_version']['minimum_required_version'].' '.get_phrase('first'));
			}
		}

		

        //Update files, folders and libraries
		$this->fileAndFolderDistributor($uploaded_folder_name);

		//run SQL file
		if(file_exists(base_path($dir.'/'.$uploaded_folder_name.'/step3_database.sql'))){
			$sql = file_get_contents(base_path($dir.'/'.$uploaded_folder_name.'/step3_database.sql'));
			if($sql){
				DB::unprepared($sql);
			}
		}

        // Exicute php or laravel's code
        if(file_exists(base_path($dir.'/'.$uploaded_folder_name.'/step4_update_data.php'))){
	        $step4Exicution = file_get_contents(base_path($dir.'/'.$uploaded_folder_name.'/step4_update_data.php'));
	        if($step4Exicution){
				eval($step4Exicution);
			}
		}


        if(array_key_exists('is_addon', $config) && strval($config['is_addon']) == "1"){
        	if($config['addon_version']['minimum_required_version'] == "0"){
				
        		return redirect()->back()->with('message', get_phrase('Addon installed successfully'));
        	}else{

        		return redirect()->back()->with('message', get_phrase('Addon updated successfully'));
        	}
        }else{
        	DB::table('global_settings')->where('key', 'version')->update(['value' => $config['product_version']['update_version']]);


        	return redirect()->back()->with('message', get_phrase('Version updated successfully'));
        }

		
    }

    function fileAndFolderDistributor($param1, $param2 = ""){
	    if($param2 == ""){
	        $param2 = $param1;
	        $uploaded_dir_path = base_path('upload/'.$param1.'/sources');
	    }else{
	        $uploaded_dir_path = $param1;
	    }

	    $uploaded_dir_paths = glob($uploaded_dir_path.'/*');


	    foreach($uploaded_dir_paths as $uploaded_sub_dir_path){
	       
	        if(is_dir($uploaded_sub_dir_path)){

	            $all_available_sub_paths = count(glob($uploaded_sub_dir_path.'/*'));

	            if ($all_available_sub_paths == 0) {
	                //Create directory
	                $application_dir_path = str_replace('upload/'.$param2.'/sources/', "", $uploaded_sub_dir_path);
	                if (!is_dir($application_dir_path)){
	                    mkdir($application_dir_path, 0777, true);
	                }
	            }else{
	                $this->fileAndFolderDistributor($uploaded_sub_dir_path, $param2);
	            }

	        }else{
	            $application_file_path = str_replace('upload/'.$param2.'/sources/', "", $uploaded_sub_dir_path);


	            //Check dir. If not exist then created
	            $file_path_arr = explode("/",$application_file_path);
	            $file_name = $file_path_arr[count($file_path_arr)-1];
	            $application_dir_path = str_replace('/'.$file_name, "", $application_file_path);
	            if (!is_dir($application_dir_path)){
	                mkdir($application_dir_path, 0777, true);
	            }

	            //Copy file to application path
	            copy($uploaded_sub_dir_path, $application_file_path);


	            //Zip file extract for any big size libraries
		        if (pathinfo($file_name, PATHINFO_EXTENSION) == 'zip') {
	                // PATH OF EXTRACTING LIBRARY FILE
	                array_pop($file_path_arr);
	                $extract_to = implode('/', $file_path_arr);
	                $library_zip = new ZipArchive;
	                $library_result = $library_zip->open($application_file_path);
	                $library_zip->extractTo($extract_to);
	                $library_zip->close();
	                unlink($application_file_path);
		        }
	        }
	    }
	}

	public static function deleteDir($dirPath) {
        if (substr($dirPath, strlen($dirPath) - 1, 1) != '/') {
            $dirPath .= '/';
        }
        $files = glob($dirPath . '*', GLOB_MARK);
        foreach ($files as $file) {
            if(file_exists($file.'.htaccess')){
                unlink($file.'.htaccess');
            }
            if (is_dir($file)) {
                self::deleteDir($file);
            } else {
                unlink($file);
            }
        }
        rmdir($dirPath);
    }


}
