package com.android.common.manager;

import android.text.TextUtils;
import android.util.Log;

import com.android.common.utils.FileUtils;
import com.android.common.utils.IOUtils;
import com.orhanobut.logger.Logger;

import java.io.InputStream;

/**
 * @author 910040
 * @version 1.0
 * @date 2018/11/13
 * 配置文件读取管理类
 * 优先读取/data/data/packageName/files/目录下的配置文件
 * 当files目录下没有配置文件时读取assets\raw目录下的
 */
public class ConfigFileManager<T> {
    
    private ConfigParse<T> mConfigureParse;

    private ConfigFileManager() {
    }

    public ConfigFileManager(ConfigParse<T> mConfigureParse) {
        this.mConfigureParse = mConfigureParse;
    }

    /**
     * 设置配置解析对象
     * @param mConfigureParse 解析配置文件对象
     */
    public void setConfigureParse(ConfigParse<T> mConfigureParse) {
        this.mConfigureParse = mConfigureParse;
    }

    /**
     * 读取配置文件form assets
     * @param fileName 文件名
     * @return config
     */
    public T readAssetsConfigure(String fileName) {
        if (mConfigureParse == null) {
            Log.e("jglee", "必须先设置ConfigParse对象");
            return null;
        }
        return readAssetsConfigure(fileName, mConfigureParse);
    }

    /**
     * 读取配置文件form assets
     * @param fileName 文件名
     * @param configParse 解析配置文件对象
     * @return config
     */
    public T readAssetsConfigure(String fileName, ConfigParse<T> configParse) {
        mConfigureParse = configParse;
        T configure = null;
        if (!TextUtils.isEmpty(fileName)) {
            String configStr = readFiles2String(fileName);
            if (!TextUtils.isEmpty(configStr)) {
                configure = mConfigureParse.parse2Object(configStr);
                if (configParse.isUpdateFile(configure)) {
                    configStr = readAssets2String(fileName);
                    configure = mConfigureParse.parse2Object(configStr);
                    String filePath = FileUtils.getFilesDir() + fileName;
                    FileUtils.writeFile(filePath, configStr, false);
                }
            } else {
                configStr = readAssets2String(fileName);
                configure = mConfigureParse.parse2Object(configStr);
                String filePath = FileUtils.getFilesDir() + fileName;
                FileUtils.writeFile(filePath, configStr, false);
            }
        } else {
            Log.e("jglee", "配置文件名不能为空");
        }
        return configure;
    }

    /**
     * 读取配置文件form raw
     * @param resID 配置文件ID
     * @param fileName 文件名
     * @return config
     */
    public T readRawConfigure(int resID, String fileName) {
        if (mConfigureParse == null) {
            Log.e("jglee", "必须先设置ConfigParse对象");
            return null;
        }
        return readRawConfigure(resID, fileName, mConfigureParse);
    }

    /**
     * 读取配置文件form raw
     * @param resID 配置文件ID
     * @param fileName 文件名
     * @param configParse 解析配置文件对象
     * @return config
     */
    public T readRawConfigure(int resID, String fileName, ConfigParse<T> configParse) {
        mConfigureParse = configParse;
        T configure = null;
        if (!TextUtils.isEmpty(fileName)) {
            String configStr = readFiles2String(fileName);
            if (!TextUtils.isEmpty(configStr)) {
                configure = mConfigureParse.parse2Object(configStr);
                if (configParse.isUpdateFile(configure)) {
                    Logger.d("update user configure file");
                    configStr = readRaw2String(resID);
                    configure = mConfigureParse.parse2Object(configStr);
                    updateConfig(fileName, configure);
                }
            } else {
                configStr = readRaw2String(resID);
                configure = mConfigureParse.parse2Object(configStr);
                updateConfig(fileName, configure);
            }
        } else {
            Log.e("jglee", "配置文件名不能为空");
        }
        return configure;
    }

    /**
     * 更新user配置文件
     * @param fileName 文件名
     * @param t 配置
     */
    public void updateConfig(String fileName, T t){
        String config = mConfigureParse.parse2String(t);
        String filePath = FileUtils.getFilesDir() + fileName;
        FileUtils.writeFile(filePath, config, false);
    }

    private String readFiles2String(String fileName) {
        String filePath = FileUtils.getFilesDir() + fileName;
        return FileUtils.readFile2String(filePath);
    }

    private String readAssets2String(String fileName) {
        InputStream inputStream = IOUtils.getIsFromAssert(fileName);
        if(inputStream != null){
            return IOUtils.inputStream2String(inputStream);
        }
        return null;
    }

    private String readRaw2String(int resId) {
        InputStream inputStream = IOUtils.getIsFromRaw(resId);
        if(inputStream != null){
            return IOUtils.inputStream2String(inputStream);
        }
        return null;
    }

}
