package me.devsaki.hentoid.fragments.downloads;

import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.material.snackbar.Snackbar;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.FragmentManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import me.devsaki.hentoid.R;
import me.devsaki.hentoid.database.ObjectBoxDB;
import me.devsaki.hentoid.database.domains.Content;
import me.devsaki.hentoid.database.domains.ErrorRecord;
import me.devsaki.hentoid.enums.ErrorType;
import me.devsaki.hentoid.events.DownloadEvent;
import me.devsaki.hentoid.util.FileHelper;
import me.devsaki.hentoid.util.LogUtil;

/**
 * Created by Robb on 11/2018
 * Info dialog for download errors details
 */
public class ErrorStatsDialogFragment extends DialogFragment {

    private static final String ID = "ID";

    private TextView details;
    private int previousNbErrors;
    private long currentId;
    private View rootView;

    public static void invoke(FragmentManager fragmentManager, long id) {
        ErrorStatsDialogFragment fragment = new ErrorStatsDialogFragment();

        Bundle args = new Bundle();
        args.putLong(ID, id);
        fragment.setArguments(args);

        fragment.setStyle(DialogFragment.STYLE_NO_FRAME, R.style.Dialog);
        fragment.show(fragmentManager, null);
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EventBus.getDefault().register(this);
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedState) {
        return inflater.inflate(R.layout.dialog_error_stats, container, false);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        rootView = view;

        if (getArguments() != null) {
            details = view.findViewById(R.id.stats_details);
            details.setText(R.string.downloads_loading);

            previousNbErrors = 0;
            long id = getArguments().getLong(ID, 0);
            currentId = id;
            if (id > 0) updateStats(id);
        }

        TextView okButton = view.findViewById(R.id.stats_ok);
        okButton.setOnClickListener(v -> this.dismiss());

        TextView logButton = view.findViewById(R.id.stats_log);
        logButton.setOnClickListener(v -> this.showErrorLog());
    }

    private void updateStats(long contentId) {
        List<ErrorRecord> errors = ObjectBoxDB.getInstance(getContext()).selectErrorRecordByContentId(contentId);
        Map<ErrorType, Integer> errorsByType = new HashMap<>();

        for (ErrorRecord error : errors) {
            if (errorsByType.containsKey(error.type)) {
                int nbErrors = errorsByType.get(error.type);
                errorsByType.put(error.type, ++nbErrors);
            } else {
                errorsByType.put(error.type, 1);
            }
        }

        StringBuilder detailsStr = new StringBuilder();

        for (ErrorType type : errorsByType.keySet()) {
            detailsStr.append(type.getName()).append(" : ");
            detailsStr.append(errorsByType.get(type));
            detailsStr.append(System.getProperty("line.separator"));
        }

        details.setText(detailsStr.toString());
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onDownloadEvent(DownloadEvent event) {
        if (event.eventType == DownloadEvent.EV_COMPLETE) {
            details.setText(R.string.download_complete);
            previousNbErrors = 0;
        } else if (event.eventType == DownloadEvent.EV_CANCEL) {
            details.setText(R.string.download_cancelled);
            previousNbErrors = 0;
        } else if ((event.eventType == DownloadEvent.EV_PROGRESS)
                    && (event.pagesKO > previousNbErrors)
                    && (event.content != null)) {
            currentId = event.content.getId();
            previousNbErrors = event.pagesKO;
            updateStats(currentId);
        }
    }

    private void showErrorLog() {
        Content content = ObjectBoxDB.getInstance(getContext()).selectContentById(currentId);
        if (content != null) {
            List<ErrorRecord> errorLog = content.getErrorLog();
            List<String> log = new ArrayList<>();

            LogUtil.LogInfo errorLogInfo = new LogUtil.LogInfo();
            errorLogInfo.logName = "Error";
            errorLogInfo.fileName = "error_log" + content.getId();
            errorLogInfo.noDataMessage = "No error detected.";

            log.add("Error log for " + content.getTitle() + " [" + content.getUniqueSiteId() + "@" + content.getSite().getDescription() + "] : " + errorLog.size() + " errors");
            for (ErrorRecord e : errorLog) log.add(e.toString());

            File logFile = LogUtil.writeLog(requireContext(), log, errorLogInfo);
            if (logFile != null) {
                Snackbar snackbar = Snackbar.make(rootView, R.string.cleanup_done, Snackbar.LENGTH_LONG);
                snackbar.setAction("READ LOG", v -> FileHelper.openFile(requireContext(), logFile));
                snackbar.show();
            }
        }
    }

    @Override
    public void onDestroy() {
        EventBus.getDefault().unregister(this);
        super.onDestroy();
    }
}

@@ -86,29 +86,119 @@
 roid
-x.annotation.NonNull;
+.view.LayoutInflater;%0Aimport android.view.View;%0Aimport android.view.ViewGroup;%0Aimport android.widget.TextView;%0A
 %0Aimp
@@ -222,23 +222,22 @@
 tation.N
+onN
 ull
-able
 ;%0Aimport
@@ -241,53 +241,36 @@
 ort 
-com.google.android.material.snackbar.Snackbar
+androidx.annotation.Nullable
 ;%0Aim
@@ -362,131 +362,61 @@
 er;%0A
+%0A
 import 
-android.view.LayoutInflater;%0Aimport android.view.View;%0Aimport android.view.ViewGroup;%0Aimport android.widget.TextView
+com.google.android.material.snackbar.Snackbar
 ;%0A%0Ai
@@ -4257,36 +4257,32 @@
                 
-    
 && (event.pagesK
@@ -4303,20 +4303,16 @@
 Errors)%0A
-    
         
@@ -5006,24 +5006,64 @@
 etected.%22;%0A%0A
+            if (errorLog != null) %7B%0A    
             
@@ -5231,32 +5231,36 @@
 %22);%0A            
+ 
+   
 for (ErrorRecord
@@ -5294,24 +5294,28 @@
 String());%0A%0A
+    
             
@@ -5384,16 +5384,20 @@
 gInfo);%0A
+    
         
@@ -5439,16 +5439,20 @@
         
+    
 Snackbar
@@ -5541,32 +5541,36 @@
                 
+    
 snackbar.setActi
@@ -5646,32 +5646,36 @@
                 
+  
+  
 snackbar.show();
@@ -5671,24 +5671,42 @@
 bar.show();%0A
+                %7D%0A
             

Fix potential NPE