package cc.winboll.studio.webpagesources.common;

/**
 * @Author ZhanGSKen@QQ.COM
 * @Date 2023/06/22 15:01:43
 * @Describe 下载线程基类
 */
import android.content.Context;
import cc.winboll.studio.libappbase.LogUtils;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLDecoder;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

abstract public class BaseDownLoadThread implements Runnable {

    public static final String TAG = "BaseDownLoadThread";

    Context mContext;
    //UserLogonUtil mUserLogonUtil;
    String mszUrl;
    String mszDowndloadName;
    protected File mfDownloadDir;
    protected File mfDownloadFile;

    //
    // 构造函数
    //
    public BaseDownLoadThread(Context context) {

    }

    //
    // 构造函数
    //
    public BaseDownLoadThread(Context context, String szUrl) {
        mContext = context;
        File fDownloadDir = new File(context.getExternalCacheDir(), "Download");
        initDownLoadEnvironment(fDownloadDir, szUrl);
    }


    //
    // 构造函数
    //
    public BaseDownLoadThread(Context context, String szUrl, String szDowndloadName) {
        mContext = context;
        mszDowndloadName = szDowndloadName;
        File fDownloadDir = new File(context.getExternalCacheDir(), "Download");
        initDownLoadEnvironment(fDownloadDir, szUrl);
    }

    //
    // 构造函数
    //
    public BaseDownLoadThread(File fDownloadDir, String szUrl) {
        initDownLoadEnvironment(fDownloadDir, szUrl);
    }

    //
    // 初始化下载环境参数
    //
    void initDownLoadEnvironment(File fDownloadDir, String szUrl) {
        mfDownloadDir = fDownloadDir;
        //LogUtils.d(TAG, "mfDownloadDir is : " + mfDownloadDir);
        if (!mfDownloadDir.exists()) {
            mfDownloadDir.mkdir();
        }
        this.mszUrl = szUrl;
        //LogUtils.d(TAG, "mszUrl is : " + mszUrl);
    }

    @Override
    public void run() {
        //LogUtils.d(TAG, "DownLoad Start : " + mszUrl);
        InputStream in = null;
        FileOutputStream fout = null;
        try {
            //LogUtils.d(TAG, "mszUrl is " + mszUrl);
            URL httpUrl = new URL(mszUrl);
            HttpURLConnection conn = (HttpURLConnection) httpUrl.openConnection();
            //conn.setRequestProperty(UserLogonUtil.getInstance(mContext).getWinBollAppHeaderKey(),
            //                        UserLogonUtil.getInstance(mContext).getWinBollAppHeaderValue());
            conn.setDoInput(true);
            conn.setDoOutput(false);
            in = conn.getInputStream();

            // 打印 Header Fields
            /*Map<String, List<String>> map = conn.getHeaderFields();
             for (String str : map.keySet()) {
             if (str != null) {
             LogUtils.d(TAG, str + map.get(str));
             }
             }*/

            // 设置文件名
            //URL absUrl = conn.getURL();
            String filename = "";

            // 文件名生成方法 1
            // 读取 Content-Disposition
            try {
                //LogUtils.d(TAG, "文件名生成方法 1");
                // 通过Content-Disposition获取文件名，这点跟服务器有关，需要灵活变通
                String szTemp = conn.getHeaderField("Content-Disposition");
                if (szTemp != null) {
                    String szSearch = "filename=\"";
                    int nSearchStart = szTemp.indexOf(szSearch);
                    int nFileNameStart = nSearchStart + szSearch.length();
                    //LogUtils.d(TAG, "nFileNameStart : " + Integer.toString(nFileNameStart));
                    int nFileNameEnd = szTemp.indexOf("\"", nFileNameStart);
                    //LogUtils.d(TAG, "nFileNameEnd : " + Integer.toString(nFileNameEnd));
                    filename = szTemp.substring(nFileNameStart, nFileNameEnd);
                }
            } catch (Exception e) {
                LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace());
            }
            //LogUtils.d(TAG, "filename is : " + filename);

            // 文件名生成方法 2
            // 读取 mszUrl
            // 如果文件名包含"/"字符
            // (例如 https://studio.zhangsken.cc/gitweb/libapputils.git/blob_plain/2aa898149aa7f0e34fe5bc11b2e70187f9f206bc:/libapputils/src/main/java/cc/winboll/studio/libapputils/LogView.java
            //  的文件名方法1就得到"filename is : libapputils/src/main/java/cc/winboll/studio/libapputils/LogView.java")
            // 或者为空就执行以下函数段
            if ((filename.lastIndexOf("/") > 0)
                || filename.trim().equals("")) {
                //LogUtils.d(TAG, "文件名生成方法 2");
                // 示例 https://studio.zhangsken.cc/gitweb/libaes.git/rss
                // 截取最后的名称"rss"。
                // 示例 https://studio.zhangsken.cc/gitweb/libaes.git/
                // 最后是反斜杆结尾。就截取最后两个斜杆之间的名称"libaes.git"。
                Pattern pattern = Pattern.compile(".*[/]([^/]+)[/]?$", Pattern.MULTILINE);
                Matcher matcher = pattern.matcher(mszUrl);
                if (matcher.find()) {
                    filename = matcher.replaceAll("$1");
                }

                //LogUtils.d(TAG, "转化文件名为可操作易读写格式");
                //LogUtils.d(TAG, "filename is : " + filename);
                // 转化文件名为可操作易读写格式
                String filenameTemp = URLDecoder.decode(filename, "UTF-8");
                //filenameTemp = filenameTemp.replace("/", "_");
                //filename = filenameTemp.replace(".", "-");
                filename = filenameTemp;

                // 如果文件名没有".*"后缀,就加上".dat"后缀
                if (filename.lastIndexOf(".") < 0) {
                    filename += ".dat";
                }
            }
            //LogUtils.d(TAG, "filename is : " + filename);

            // 如果指定了保存名称就用指定的名称
            if (mszDowndloadName != null && !mszDowndloadName.equals("")) {
                filename = mszDowndloadName;
            }

            mfDownloadFile = createSavedFile(filename);
            // 如果文件存在就退出，没有就创建一个并下载
            if (mfDownloadFile.exists()) {
                LogUtils.d(TAG, "mfDownloadFile : " + mfDownloadFile.getPath());
                fout = new FileOutputStream(mfDownloadFile);
                byte[] buffer = new byte[1024];
                int len;
                while ((len = in.read(buffer)) != -1) {
                    fout.write(buffer, 0, len);
                }
                LogUtils.i(TAG, "DownLoad is well done : " + mfDownloadFile.getPath());
                // 处理接收到的项目列表文件
                handleDownloadFile();
            }
        } catch (Exception e) {
            LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace());
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace());
                }
            }
            if (fout != null) {
                try {
                    fout.close();
                } catch (IOException e) {
                    LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace());
                }
            }
        }
    }

    //
    //
    File createSavedFile(String szOriginDownloadName) {
        File fOriginDownload = new File(mfDownloadDir, szOriginDownloadName);
        if (!fOriginDownload.exists()) {
            // 如果该文件名的文件不存在，就表示可以保存为该文件名
            // 预先创建新文件
            try {
                fOriginDownload.createNewFile();
            } catch (IOException e) {
                LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
            }
            return fOriginDownload;
        }

        // 校验文件是否已存在，若存在就重命名新文件名
        File fCheck = fOriginDownload;
        int nAddName = 1;
        while (fCheck.exists()) {
            int nPoint = szOriginDownloadName.lastIndexOf(".");
            if (nPoint > -1) {
                LogUtils.d(TAG, "nPoint > -1");
                fCheck = new File(mfDownloadDir, File.separator + szOriginDownloadName.substring(0, nPoint)  + "(" + Integer.toString(nAddName) + ")." + szOriginDownloadName.substring(nPoint + 1));
            } else {
                LogUtils.d(TAG, "nPoint > -1 else");
                fCheck = new File(mfDownloadDir, File.separator + szOriginDownloadName + "(" + Integer.toString(nAddName) + ")");
            }
            LogUtils.d(TAG, "nAddName++");
            nAddName++;
        }
        // 预先创建新文件
        try {
            fCheck.createNewFile();
        } catch (IOException e) {
            LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
        }
        return fCheck;
    }

    //
    // 文件下载后的文件处理函数
    //
    abstract protected void handleDownloadFile();

}
