<?php
namespace DistributeHelper;
error_reporting(E_ALL & ~E_NOTICE);
include "Utility.php";

class PackageClass
{
	private static $config = null;     //配置信息
	//当所有包都安装完毕后
	public static function postUpdate($vendorDir,$rootPkg,$vendorPkgs)
	{
		//初始化
		if(! self::initialize($vendorDir)){
			self::setUpdateFailed('INITIALIZE_FAILED');
			return false;
		}
		
		//依赖库都已下载,默认先给个进度
		self::updateProgress(0,100);
		
		//逐个依赖仓库操作
		self::postUpdateVendorPkgs($vendorDir,$vendorPkgs);
		
		//顶层仓库操作
		self::postUpdateRootPkg($vendorDir,$rootPkg);
		
		//全部操作完毕
		self::setUpdateOK(true);
		return true;
	}
	
	private static function postUpdateVendorPkgs($vendorDir,$vendorPkgs)
	{
		foreach($vendorPkgs as $i=>$pkg){
			//获取包信息
			$repoDir = pathJoin($vendorDir,$pkg->getName());
			$packageInfo = self::getPackageInfo($vendorDir,$repoDir,$pkg);
			
			//获取当前包的module文件
			self::fetchModuleFiles($packageInfo);
			
			//获取当前包的common文件
			self::fetchCommonFiles($packageInfo);

			//获取当前包的config文件
			self::fetchConfigFiles($packageInfo);
						
			//更新部署进度
			$percent = intval(100.0 * ($i+1) / count(vendorPkgs));
			self::updateProgress(1,$percent);
		}
	}
	private static function postUpdateRootPkg($vendorDir,$pkg)
	{
		//获取包信息
		$repoDir = dirname($vendorDir);
		$packageInfo = self::getPackageInfo($vendorDir,$repoDir,$pkg);
		
		//获取当前包的module文件
		self::fetchModuleFiles($packageInfo);
		
		//获取当前包的common文件
		self::fetchCommonFiles($packageInfo);

		//获取当前包的config文件
		self::fetchConfigFiles($packageInfo);
		
		//注册全局路径
		self::registerPath($packageInfo);
		
		//注册自启动程序
		self::registerAutorun($packageInfo);
	}
	//初始化
	private static function initialize($vendorDir)
	{
		//创建.distribute目录
		$distributeDir = pathJoin(dirname($vendorDir),'.distribute');
		if( !file_exists($distributeDir) ){
			mkdir($distributeDir,0777,true);
		}
		
		//创建module目录
		$moduleDir = pathJoin(dirname($vendorDir),'module');
		if( !file_exists($moduleDir) ){
			mkdir($moduleDir,0777,true);
		}
		
		//设置日志文件路径
		if(! defined(LOG_PATH)){
			$logPath = pathJoin($distributeDir,'log.txt');
			define('LOG_PATH',$logPath);
		}

		//设置进度文件路径
		if(! defined(PROGRESS_PATH)){
			$progressPath = pathJoin($distributeDir,'progress.txt');
			define('PROGRESS_PATH',$progressPath);
		}
		
		//获取部署配置信息
		$cfgPath = pathJoin($distributeDir,'config.json');
		$config = loadConfig($cfgPath);
		if(!$config){
			printf("Failed to load distribute config -- %s\n",$cfgPath);
			return false;
		}
		self::$config = $config;

		return true;
	}
	
	private static function updateProgress($step,$percent)
	{
		file_put_contents(PROGRESS_PATH,strval($percent));
	}
	private static function setUpdateFailed($msg)
	{
		file_put_contents(PROGRESS_PATH,"FAIL:" . $msg);
	}
	private static function setUpdateOK($restart)
	{
		if($restart){
			file_put_contents(PROGRESS_PATH,"OK:NEED_RESTART");
		}
		else{
			file_put_contents(PROGRESS_PATH,"OK:NO_RESTART");
		}
	}
	//获取包相关信息
	private static function getPackageInfo($vendorDir,$repoDir,$pkg)
	{
		$config = self::$config;
		
		$cfgPath = pathJoin($repoDir,'composer.json');
		$data = json_decode(file_get_contents($cfgPath), true);
		$moduleName = $data["distribute-helper"]["module-name"];

		
		//获取安装目录
		$rootDir = dirname($vendorDir);
		$commonDir = pathJoin($rootDir,'siscom');
		$configDir = pathJoin($rootDir,'config',$moduleName);
		$moduleDir = pathJoin($rootDir,'module',$moduleName . '-' . $pkg->getPrettyVersion());
		
		//获取缓存目录
		$cacheName = str_replace('/','-',$pkg->getName()) . '-' . $pkg->getPrettyVersion();
		$cacheDir = pathJoin($config['cache-dir'],$cacheName);
		
		//返回包的相关信息
		return array(
			"repoName" => $pkg->getName(),
			"version" => $pkg->getPrettyVersion(),
			"cacheDir" => $cacheDir,
			"ossHost" => $config['oss-host'],
			"moduleName" => $moduleName,
			"commonDir" => $commonDir,
			"configDir" => $configDir,
			"moduleDir" => $moduleDir,
			"helper" => $data["distribute-helper"],
		);
	}
	
	//下载包module文件
	private static function fetchModuleFiles($packageInfo)
	{
		$cacheDir = $packageInfo['cacheDir'];
		$repoName = $packageInfo['repoName'];
		$version = $packageInfo['version'];
		$moduleDir = $packageInfo['moduleDir'];
		$ossHost = $packageInfo['ossHost'];
		
		$moduleFiles = $packageInfo['helper']['module-files'];
		if(! $moduleFiles){
			logInfo($repoName,'no module files defined. skip.');
			return;
		}
		
		foreach($moduleFiles as $fileInfo){
			$fileName = $fileInfo['name'];
			printf("[%s] fetching file -- %s\n",$repoName,$fileName);

			//下载文件到缓存区
			$filePath = downloadToDir($ossHost,$repoName,$version,$fileName,$cacheDir);
			if(! $filePath ){
				printf("[%s] fetch file failed -- %s\n",$repoName,$fileName);
				continue;
			}

			// 解压文件
			if( isZipFile($fileName) ){
				if(! unzipFile($filePath,$moduleDir)) {
					printf("[%s] unzip file failed -- %s\n ",$repoName,$fileName);
					unlink($filePath);
				}
			}
		}
	}
	
	//下载包common文件
	private static function fetchCommonFiles($packageInfo)
	{
		$cacheDir = $packageInfo['cacheDir'];
		$repoName = $packageInfo['repoName'];
		$version = $packageInfo['version'];
		$commonDir = $packageInfo['commonDir'];
		$ossHost = $packageInfo['ossHost'];
		$commonFiles = $packageInfo['helper']['common-files'];
		if(! $commonFiles){
			logInfo($repoName,'no common files defined. skip.');
			return;
		}
		foreach($commonFiles as $fileInfo){
			$fileName = $fileInfo['name'];
			printf("[%s] fetching common file -- %s\n",$repoName,$fileName);
			//下载文件到缓存区
			$filePath = downloadToDir($ossHost,$repoName,$version,$fileName,$cacheDir);
			if(! $filePath ){
				printf("[%s] fetch common file failed -- %s\n",$repoName,$fileName);
				continue;
			}

			// 解压文件
			if( isZipFile($fileName) ){
				if(! unzipFile($filePath,$commonDir)) {
					printf("[%s] unzip common file failed -- %s\n ",$repoName,$fileName);
					unlink($filePath);
				}
			}
		}
	}
	
	//下载包config文件
	private static function fetchConfigFiles($packageInfo)
	{
		$cacheDir = $packageInfo['cacheDir'];
		$repoName = $packageInfo['repoName'];
		$version = $packageInfo['version'];
		$configDir = $packageInfo['configDir'];
		$ossHost = $packageInfo['ossHost'];
		$configFiles = $packageInfo['helper']['config-files'];
		if(! $configFiles){
			logInfo($repoName,'no config files defined. skip.');
			return;
		}
		foreach($configFiles as $fileInfo){
			$fileName = $fileInfo['name'];
			printf("[%s] fetching config file -- %s\n",$repoName,$fileName);
			//下载文件到缓存区
			$filePath = downloadToDir($ossHost,$repoName,$version,$fileName,$cacheDir);
			if(! $filePath ){
				printf("[%s] fetch config file failed -- %s\n",$repoName,$fileName);
				continue;
			}

			// 解压文件
			if( isZipFile($fileName) ){
				if(! unzipFile($filePath,$configDir)) {
					printf("[%s] unzip config file failed -- %s\n ",$repoName,$fileName);
					unlink($filePath);
				}
			}
		}
	}
	
	private static function registerPath($packageInfo)
	{
	}
	
	private static function registerAutorun($packageInfo)
	{
	}
}