package com.ruoyi.ueditorConfig;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONException;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.ueditorConfig.define.ActionMap;

import java.io.*;
import java.util.HashMap;
import java.util.Map;


/**
 * 配置管理器
 * @author hancong03@baidu.com
 *
 */
public final class ConfigManager {

	private final String config = "{\n" +
			"    \"imageActionName\": \"uploadimage\",\n" +
			"    \"imageFieldName\": \"upfile\",\n" +
			"    \"imageMaxSize\": 2048000,\n" +
			"    \"imageAllowFiles\": [\".png\", \".jpg\", \".jpeg\", \".gif\", \".bmp\"],\n" +
			"    \"imageCompressEnable\": true,\n" +
			"    \"imageCompressBorder\": 1600,\n" +
			"    \"imageInsertAlign\": \"none\",\n" +
			"    \"imageUrlPrefix\": \"\",\n" +
			"    \"localSavePathPrefix\":\"/smltplat/upload/ueditor\",\n" +
			"    \"imagePathFormat\": \"/image/{yyyy}{mm}{dd}\",\n" +
			"    \"snapscreenActionName\": \"uploadimage\",\n" +
			"    \"snapscreenPathFormat\": \"/image/{yyyy}{mm}{dd}\",\n" +
			"    \"snapscreenUrlPrefix\": \"\",\n" +
			"    \"snapscreenInsertAlign\": \"none\",\n" +
			"    \"catcherLocalDomain\": [\"127.0.0.1\", \"localhost\", \"img.baidu.com\"],\n" +
			"    \"catcherActionName\": \"catchimage\",\n" +
			"    \"catcherFieldName\": \"source\",\n" +
			"    \"catcherPathFormat\": \"/image/{yyyy}{mm}{dd}\",\n" +
			"    \"catcherUrlPrefix\": \"\",\n" +
			"    \"catcherMaxSize\": 2048000,\n" +
			"    \"catcherAllowFiles\": [\".png\", \".jpg\", \".jpeg\", \".gif\", \".bmp\"],\n" +
			"\t\"catchRemoteImageEnable\": false,\n" +
			"    \"videoActionName\": \"uploadvideo\",\n" +
			"    \"videoFieldName\": \"upfile\",\n" +
			"    \"videoPathFormat\": \"/video/{yyyy}{mm}{dd}\",\n" +
			"    \"localSavePathPrefix\":\"/smltplat/upload/ueditor\",\n" +
			"    \"videoUrlPrefix\": \"\",\n" +
			"    \"videoMaxSize\": 102400000,\n" +
			"    \"videoAllowFiles\": [\n" +
			"        \".flv\", \".swf\", \".mkv\", \".avi\", \".rm\", \".rmvb\", \".mpeg\", \".mpg\",\n" +
			"        \".ogg\", \".ogv\", \".mov\", \".wmv\", \".mp4\", \".webm\", \".mp3\", \".wav\", \".mid\"],\n" +
			"    \"fileFieldName\": \"upfile\",\n" +
			"    \"filePathFormat\": \"/file/{yyyy}{mm}{dd}\",\n" +
			"    \"localSavePathPrefix\":\"/smltplat/upload/ueditor\",\n" +
			"    \"fileUrlPrefix\": \"\",\n" +
			"    \"fileMaxSize\": 51200000,\n" +
			"    \"fileAllowFiles\": [\n" +
			"        \".png\", \".jpg\", \".jpeg\", \".gif\", \".bmp\",\n" +
			"        \".flv\", \".swf\", \".mkv\", \".avi\", \".rm\", \".rmvb\", \".mpeg\", \".mpg\",\n" +
			"        \".ogg\", \".ogv\", \".mov\", \".wmv\", \".mp4\", \".webm\", \".mp3\", \".wav\", \".mid\",\n" +
			"        \".rar\", \".zip\", \".tar\", \".gz\", \".7z\", \".bz2\", \".cab\", \".iso\",\n" +
			"        \".doc\", \".docx\", \".xls\", \".xlsx\", \".ppt\", \".pptx\", \".pdf\", \".txt\", \".md\", \".xml\"\n" +
			"    ],\n" +
			"    \"imageManagerActionName\": \"listimage\",\n" +
			"    \"imageManagerListPath\": \"/image/\",\n" +
			"    \"imageManagerListSize\": 20,\n" +
			"    \"imageManagerUrlPrefix\": \"\",\n" +
			"    \"imageManagerInsertAlign\": \"none\",\n" +
			"    \"imageManagerAllowFiles\": [\".png\", \".jpg\", \".jpeg\", \".gif\", \".bmp\"],\n" +
			"    \"fileManagerActionName\": \"listfile\", \n" +
			"    \"fileManagerListPath\": \"/upload/file/\",\n" +
			"    \"fileManagerUrlPrefix\": \"\",\n" +
			"    \"fileManagerListSize\": 20,\n" +
			"    \"fileManagerAllowFiles\": [\n" +
			"        \".png\", \".jpg\", \".jpeg\", \".gif\", \".bmp\",\n" +
			"        \".flv\", \".swf\", \".mkv\", \".avi\", \".rm\", \".rmvb\", \".mpeg\", \".mpg\",\n" +
			"        \".ogg\", \".ogv\", \".mov\", \".wmv\", \".mp4\", \".webm\", \".mp3\", \".wav\", \".mid\",\n" +
			"        \".rar\", \".zip\", \".tar\", \".gz\", \".7z\", \".bz2\", \".cab\", \".iso\",\n" +
			"        \".doc\", \".docx\", \".xls\", \".xlsx\", \".ppt\", \".pptx\", \".pdf\", \".txt\", \".md\", \".xml\"\n" +
			"    ]\n" +
			"\n" +
			"}\n";

	private final String rootPath;
	private final String originalPath;
	private final String contextPath;
	private static final String configFileName = "config.json";
	private String parentPath = null;
	private JSONObject jsonConfig = null;
	// 涂鸦上传filename定义
	private final static String SCRAWL_FILE_NAME = "scrawl";
	// 远程图片抓取filename定义
	private final static String REMOTE_FILE_NAME = "remote";

	/*
	 * 通过一个给定的路径构建一个配置管理器， 该管理器要求地址路径所在目录下必须存在config.properties文件
	 */
	private ConfigManager ( String rootPath, String contextPath, String uri ) throws FileNotFoundException, IOException {

		rootPath = rootPath.replace( "\\", "/" );

		this.rootPath = rootPath;
		this.contextPath = contextPath;
		this.originalPath = "src/main/java/com/ruoyi/system/util/ueditor/json/ueditorConfig.json";

		this.initEnv();

	}

	/**
	 * 配置管理器构造工厂
	 * @param rootPath 服务器根路径
	 * @param contextPath 服务器所在项目路径
	 * @param uri 当前访问的uri
	 * @return 配置管理器实例或者null
	 */
	public static ConfigManager getInstance ( String rootPath, String contextPath, String uri ) {

		try {
			return new ConfigManager(rootPath, contextPath, uri);
		} catch ( Exception e ) {
			e.printStackTrace();
			return null;
		}

	}

	// 验证配置文件加载是否正确
	public boolean valid () {
		return this.jsonConfig != null;
	}

	public JSONObject getAllConfig () {

		return this.jsonConfig;

	}

	public Map<String, Object> getConfig ( int type ) throws JSONException {

		Map<String, Object> conf = new HashMap<String, Object>();
		String savePath = null;
		String localSavePathPrefix = null;

		switch ( type ) {

			case ActionMap.UPLOAD_FILE:
				conf.put( "isBase64", "false" );
				conf.put( "maxSize", this.jsonConfig.getLong( "fileMaxSize" ) );
				conf.put( "allowFiles", this.getArray( "fileAllowFiles" ) );
				conf.put( "fieldName", this.jsonConfig.getString( "fileFieldName" ) );
				savePath = this.jsonConfig.getString( "filePathFormat" );
				localSavePathPrefix = this.jsonConfig.getString("localSavePathPrefix");
				break;

			case ActionMap.UPLOAD_IMAGE:
				conf.put( "isBase64", "false" );
				conf.put( "maxSize", this.jsonConfig.getLong( "imageMaxSize" ) );
				conf.put( "allowFiles", this.getArray( "imageAllowFiles" ) );
				conf.put( "fieldName", this.jsonConfig.getString( "imageFieldName" ) );
				savePath = this.jsonConfig.getString( "imagePathFormat" );
				localSavePathPrefix = this.jsonConfig.getString("localSavePathPrefix");
				break;

			case ActionMap.UPLOAD_VIDEO:
				conf.put( "maxSize", this.jsonConfig.getLong( "videoMaxSize" ) );
				conf.put( "allowFiles", this.getArray( "videoAllowFiles" ) );
				conf.put( "fieldName", this.jsonConfig.getString( "videoFieldName" ) );
				savePath = this.jsonConfig.getString( "videoPathFormat" );
				localSavePathPrefix = this.jsonConfig.getString("localSavePathPrefix");
				break;

			case ActionMap.UPLOAD_SCRAWL:
				conf.put( "filename", ConfigManager.SCRAWL_FILE_NAME );
				conf.put( "maxSize", this.jsonConfig.getLong( "scrawlMaxSize" ) );
				conf.put( "fieldName", this.jsonConfig.getString( "scrawlFieldName" ) );
				conf.put( "isBase64", "true" );
				savePath = this.jsonConfig.getString( "scrawlPathFormat" );
				break;

			case ActionMap.CATCH_IMAGE:
				conf.put( "filename", ConfigManager.REMOTE_FILE_NAME );
				conf.put( "filter", this.getArray( "catcherLocalDomain" ) );
				conf.put( "maxSize", this.jsonConfig.getLong( "catcherMaxSize" ) );
				conf.put( "allowFiles", this.getArray( "catcherAllowFiles" ) );
				conf.put( "fieldName", this.jsonConfig.getString( "catcherFieldName" ) + "[]" );
				savePath = this.jsonConfig.getString( "catcherPathFormat" );
				localSavePathPrefix = this.jsonConfig.getString("localSavePathPrefix");
				break;

			case ActionMap.LIST_IMAGE:
				conf.put( "allowFiles", this.getArray( "imageManagerAllowFiles" ) );
				conf.put( "dir", this.jsonConfig.getString( "imageManagerListPath" ) );
				conf.put( "count", this.jsonConfig.getIntValue( "imageManagerListSize" ) );
				break;

			case ActionMap.LIST_FILE:
				conf.put( "allowFiles", this.getArray( "fileManagerAllowFiles" ) );
				conf.put( "dir", this.jsonConfig.getString( "fileManagerListPath" ) );
				conf.put( "count", this.jsonConfig.getIntValue( "fileManagerListSize" ) );
				break;

		}

		conf.put( "savePath", savePath );
		conf.put( "localSavePathPrefix", localSavePathPrefix );
		conf.put( "rootPath", this.rootPath );

		return conf;

	}

	private void initEnv () throws FileNotFoundException, IOException {

		try{

			this.jsonConfig = jsonConfig;
		} catch ( Exception e ) {
			this.jsonConfig = null;
		}

	}

	private String getConfigPath () {
		return this.parentPath + File.separator + ConfigManager.configFileName;
	}

	private String[] getArray ( String key ) throws JSONException {

		JSONArray jsonArray = this.jsonConfig.getJSONArray( key );
		String[] result = new String[ jsonArray.size() ];

		for ( int i = 0, len = jsonArray.size(); i < len; i++ ) {
			result[i] = jsonArray.getString( i );
		}

		return result;

	}

	public static String  readFile (String path) throws IOException {
		path = java.net.URLDecoder.decode(path, "utf-8");
		StringBuilder builder = new StringBuilder();

		try {
			InputStreamReader reader = new InputStreamReader( new FileInputStream( path ), "UTF-8" );
			BufferedReader bfReader = new BufferedReader( reader );

			String tmpContent = null;

			while ( ( tmpContent = bfReader.readLine() ) != null ) {
				builder.append( tmpContent );
			}

			bfReader.close();

		} catch ( UnsupportedEncodingException e ) {
			// 忽略
		}

		return filter( builder.toString() );

	}

	// 过滤输入字符串, 剔除多行注释以及替换掉反斜杠
	private static String filter(String input) {

		return input.replaceAll( "/\\*[\\s\\S]*?\\*/", "" );

	}

}
