package com.xypower.mpapp;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.os.FileObserver;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.Messenger;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.MenuItem;

import com.xypower.common.MicroPhotoContext;
import com.xypower.mpapp.databinding.ActivityLogBinding;
import com.xypower.mpapp.utils.RandomReader;

import java.io.File;

public class LogActivity extends AppCompatActivity {

    public static final String TAG = "MPLOG";

    public static final int MSG_WHAT_LOG_OBSERVER = MicroPhotoService.MSG_WHAT_MAX + 10;

    public static final int MAX_LOG_LINES = 480;
    public static final int MIN_LOG_LINES = 120;

    private ActivityLogBinding binding;

    private Handler mHandler = null;

    private LogFileObserver mLogFileObserver = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        binding = ActivityLogBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        binding.logs.setText("");
        binding.logs.setMovementMethod(ScrollingMovementMethod.getInstance());
        binding.logs.setScrollbarFadingEnabled(false);

        mHandler = new Handler(Looper.myLooper()) {
            @Override
            public void handleMessage(@NonNull Message msg) {
                switch (msg.what) {
                    case MSG_WHAT_LOG_OBSERVER:
                    {
                        byte[] bytes = (byte[])msg.obj;
                        int bytesRead = msg.arg1;
                        String log = null;
                        try {
                            log = new String(bytes, 0, bytesRead, "UTF-8");
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        if (log != null) {
                            binding.logs.append(log);
                            int offset = binding.logs.getLineCount() * binding.logs.getLineHeight();
                            if (offset > binding.logs.getHeight()) {
                                binding.logs.scrollTo(0, offset - binding.logs.getHeight() + binding.logs.getLineHeight());
                            }
                        }
                    }
                    break;
                }
            }
        };

    }


    @Override
    protected void onResume() {
        // call the superclass method first
        super.onResume();

        try {
            String logFilePath = MicroPhotoContext.buildAppDir(this.getApplicationContext());
            logFilePath += "logs";
            File file = new File(logFilePath);
            if (!file.exists()) {
                file.mkdirs();
            }
            logFilePath += "/log.txt";
            file = new File(logFilePath);
            if (!file.exists()) {
                file.createNewFile();
            }

            mLogFileObserver = new LogFileObserver(logFilePath);
            mLogFileObserver.startWatching();
            Log.i(TAG, "Log Observer Started");

            int lines = binding.logs.getLineCount();
            if (lines > MAX_LOG_LINES) {
                int excessLineNumber = lines - MIN_LOG_LINES;
                int eolIndex = -1;
                CharSequence charSequence = binding.logs.getText();
                for (int i = 0; i < excessLineNumber; i++) {
                    do {
                        eolIndex++;
                    } while (eolIndex < charSequence.length() && charSequence.charAt(eolIndex) != '\n');
                }
                if (eolIndex < charSequence.length()) {
                    binding.logs.getEditableText().delete(0, eolIndex + 1);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void onPause() {
        // call the superclass method first
        super.onPause();

        try {
            if (mLogFileObserver != null) {
                mLogFileObserver.stopWatching();
                mLogFileObserver = null;
                Log.i(TAG, "Log Observer Stopped");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                // todo: goto back activity from here

                finish();
                return true;

            default:
                return super.onOptionsItemSelected(item);
        }
    }


    private class LogFileObserver extends FileObserver {

        private long mOffset = 0;
        private String mPath = null;
        public LogFileObserver(String path) {
            super(path, FileObserver.MODIFY | FileObserver.CREATE);

            mPath = path;
            File file = new File(path);
            if (file.exists()) {
                mOffset = file.length();
            }
        }
        @Override
        public void onEvent(int event, String s) {
            int e = event & FileObserver.ALL_EVENTS;

            if (e == FileObserver.MODIFY) {
                File file = new File(mPath);
                long newOffset = file.length();
                if (newOffset > mOffset) {
                    RandomReader reader = new RandomReader(mPath, mOffset);

                    byte[] bytes = new byte[(int)(newOffset - mOffset)];
                    int bytesRead = reader.read(bytes);
                    mOffset += bytesRead;

                    Message msg = Message.obtain();
                    msg.what = MSG_WHAT_LOG_OBSERVER;
                    msg.obj = bytes;
                    msg.arg1 = bytesRead;
                    mHandler.sendMessage(msg);
                }
            } else if (e == FileObserver.CREATE) {
                mOffset = 0;
            }
        }
    }

}