package com.hclogger;

import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.text.TextUtils;
import android.util.Log;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;

/**
 * Created by zhaozhao on 2018/4/26.
 */

public class LogManager {

    public static final String FILE = "file";
    public static final String INFO = "info";
    public static final String DEBUG = "debug";
    public static final String WARN = "warn";
    public static final String ERROR = "error";

    private static final String LAST_LOG_TIME = "last_log_TIME";

    private static final String TAG = LogManager.class.getSimpleName();
    private static LogManager mInstance;
    private static String PATH;
    private static Context sContext;
    public static final String FOLD_NAME = "log";
    private static final String LOG_FILE_FORMAT = "yyyy-MM-dd_HH-mm-ss";
    private SimpleDateFormat mLogTimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    private SimpleDateFormat mLogFileFormat = new SimpleDateFormat(LOG_FILE_FORMAT);
    private long mLastLogTime = 0;
    //默认单个文件大小
    private long defaultSize = 5 * 1024 * 1024;
    //默认拆分文件间隔时长
    private long fileTimeOut = 1000 * 60 * 60 * 24;
    //默认最大文件个数
    private int defaultMaxFileCount = 20;
    //默认文件大小
    private PrintWriter mPW = null;

    private String lastLogLevel = "";


    private LogManager() {

    }

    public static LogManager getInstance(Context context) {
        if (mInstance == null) {
            mInstance = new LogManager();
        }
        if (TextUtils.isEmpty(PATH)) {
            PATH = context.getExternalFilesDir(FOLD_NAME).getPath() + "/";
        }
        sContext = context;
        return mInstance;
    }

    public void setDefaultSize(int size) {
        this.defaultSize = size * 1024 * 1024;
    }

    public void setFileTimeOut(int hour) {
        this.fileTimeOut = hour * 1000 * 60 * 60;
    }

    public void setDefaultFileCount(int count) {
        this.defaultMaxFileCount = count;
    }

    public void startLog() {
        long now = System.currentTimeMillis();
        String filePath = null;
        File[] sortFiles = getFiles();
        if (mPW != null) {
            return;
        }
        if (sortFiles != null && sortFiles.length > 0) {
            String lastFileName = sortFiles[0].getName();
            ParsePosition parsePosition = new ParsePosition(0);
            Date date = mLogFileFormat.parse(lastFileName, parsePosition);
            //最近修改文件超过24小时拆分文件 文件大小超过5mb
            if (now - date.getTime() > fileTimeOut || sortFiles[0].length() > defaultSize) {
                String timeStr = mLogFileFormat.format(new Date(now));
                filePath = PATH + timeStr;
            } else {
                filePath = PATH + lastFileName;
            }
        } else {
            String timeStr = mLogFileFormat.format(new Date(now));
            filePath = PATH + timeStr;
        }

        try {
            if (mPW != null) {
                stop();
            }

            mPW = new PrintWriter(new BufferedWriter(new FileWriter(filePath, true)));
            delOverFiles();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    //可以停止在当前文件log，新建一个新的文件进行 log
    public void rollLogFile() {
        Log.i(TAG, "rollLogFile");

        String timeStr = mLogFileFormat.format(new Date(System.currentTimeMillis()));
        String filePath = PATH + timeStr;
        try {
            if (mPW != null) {
                stop();
            }
            mPW = new PrintWriter(new BufferedWriter(new FileWriter(filePath)));
            delOverFiles();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //获取最近新建修改的文件
    private File[] getFiles() {
        File files = new File(PATH);
        File[] listFiles = files.listFiles();
        //排序  按修改时间递增
        Arrays.sort(listFiles, new Comparator<File>() {
            @Override
            public int compare(File f1, File f2) {
                long diff = f1.lastModified() - f2.lastModified();
                if (diff > 0)
                    return -1;
                else if (diff == 0)
                    return 0;
                else
                    return 1;
            }

            public boolean equals(Object obj) {
                return true;
            }
        });
        return listFiles;
    }

    //文件数超过defaultMaxFileCount时 删除多余文件
    public void delOverFiles() {
        File[] files = getFiles();
        if (files != null && files.length > defaultMaxFileCount) {
            for (int i = defaultMaxFileCount; i < files.length; i++) {
                files[i].delete();
            }
        }
    }

    private String getLevelStr(String level) {
        String headStr = "";
        //headStr需要和ios端统一使用一种emoji
        switch (level) {
            case FILE:
                headStr = "\uD83D\uDCDA";
                break;
            case INFO:
                headStr = "\uD83D\uDCDD️️";
                break;
            case DEBUG:
                headStr = "\uD83D\uDC1D";
                break;
            case WARN:
                headStr = "⚡️";
                break;
            case ERROR:
                headStr = "\uD83D\uDEA8";
                break;
        }
        return headStr;
    }

    public void debug(String msg, String level) {
        String levelStr = getLevelStr(level);
        if (mPW != null) {
            long now = System.currentTimeMillis();
            mPW.print(mLogTimeFormat.format(new Date(now)));
            mPW.print(levelStr);
            mPW.print(":");
            mPW.println(msg);

            if (TextUtils.equals(lastLogLevel, level)) {
                if (now - mLastLogTime > 1000) {
                    mLastLogTime = now;
                    mPW.flush();
                }
            } else {
                mPW.flush();
                lastLogLevel = level;
            }

        } else {
            startLog();
            debug(msg, level);
        }
    }

    public void stop() {
        if (mPW != null) {
            mPW.flush();
            mPW.close();
            mPW = null;
            //保存最近一次停止printlog 的时间
            long lastLogTime = System.currentTimeMillis();
            SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(sContext);
            SharedPreferences.Editor edit = pref.edit();
            edit.putLong(LAST_LOG_TIME, lastLogTime);
            edit.apply();
        }
    }

}
