package com.unibuy.smartdevice.exception;

import static android.content.Context.MODE_PRIVATE;

import android.content.Context;
import android.os.Environment;
import android.util.Log;

import com.unibuy.smartdevice.tools.Tools;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

public class Logs {
    private String message;
    private String className;
    private String methodName;
    private int lineNumber;

    public Logs(Class<?> clazz) {
        this.message = "";
        this.className = clazz.getSimpleName();
        this.methodName = "";
        this.lineNumber = 0;
    }

    public String getMessage() {
        return this.message;
    }

    public String getClassName() {
        return className;
    }

    public synchronized void writeFile(String data) {
        File txtDebug = new File(Tools.getExternalFilesDir(), "debug.txt");
        if (txtDebug.exists()) {
            txtDebug.setReadable(true, false);
            txtDebug.setWritable(true, false);
        }

        String dateTime = Tools.getTimeStampByNow("yyyy-MM-dd HH:mm:ss.SSS");
        data = dateTime + " " + data;

        try (FileOutputStream fos = new FileOutputStream(txtDebug, true)) {  // try-with-resources 自動 close()
            fos.write(data.getBytes(StandardCharsets.UTF_8));
            fos.write("\n".getBytes(StandardCharsets.UTF_8));  // 換行
            fos.flush();
        } catch (IOException e) {
            warning(e);
        }
    }

    public String getInfo() {
        return this.className+"."+this.methodName+"("+this.lineNumber+")";
    }

    public void debug(String message) {
        this.message = message;
        Log.d(this.className, "DEBUG ["+getClassName()+"]"+this.message);
        writeFile("DEBUG ["+getClassName()+"]"+this.message);
    }

    public void info(String message) {
        this.message = message;
        Log.i(this.className, "INFO ["+getClassName()+"]"+this.message);
        writeFile("INFO ["+getClassName()+"]"+this.message);
    }

    public void ignore(Exception e) {
        StackTraceElement[] stackTrace = e.getStackTrace();
        if (stackTrace.length > 0) {
            StackTraceElement element = stackTrace[0];
            className = element.getClassName();
            methodName = element.getMethodName();
            lineNumber = element.getLineNumber();
        }
        ignore(e.getLocalizedMessage());
    }

    public void ignore(String message) {
        this.message = message;
        Log.w(this.className, "IGNORE ["+getClassName()+"/"+getInfo()+"]"+this.message);
        writeFile("IGNORE ["+getClassName()+"/"+getInfo()+"]"+this.message);
    }

    public void warning(Exception e) {
        StackTraceElement[] stackTrace = e.getStackTrace();
        if (stackTrace.length > 0) {
            StackTraceElement element = stackTrace[0];
            className = element.getClassName();
            methodName = element.getMethodName();
            lineNumber = element.getLineNumber();
        }
        this.message = e.getLocalizedMessage();
        Log.w(this.className, "WARNING ["+getInfo()+"]"+this.message);
        writeFile("WARNING ["+getInfo()+"]"+this.message);
    }

    public void error(ErrorCode errorCode, String message) {
        this.message = message;
        Log.i(this.className, "ERROR ["+getClassName()+"("+errorCode.getCode()+")"+errorCode.getMessage()+"]"+this.message);
        writeFile("ERROR ["+getClassName()+"("+errorCode.getCode()+")"+errorCode.getMessage()+"]"+this.message);
    }

    public void update(String key, String value) {
        update(key, value, "");
    }

    public void update(String key, String value, String unit) {
        this.message = value;
        if (!unit.isEmpty()) this.message = this.message + " " + unit;
        Log.w(this.className, "UPDATE ["+this.className+"]"+this.message);
        writeFile("UPDATE ["+this.className+"]{\""+key+"\":\""+value+"\"}");
    }

    public void clearMessage() {
        this.message = "";
    }
}
