package com.xypower.common;

import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Environment;
import android.text.TextUtils;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.util.List;

public class MicroPhotoContext {

    public static final String PACKAGE_NAME_MPAPP = "com.xypower.mpapp";
    public static final String PACKAGE_NAME_MPMASTER = "com.xypower.mpmaster";
    public final static String DEFAULT_MASTER_URL = "http://180.166.218.222:40101/";
    public final static String MASTER_URL_CMDID = "cmdid";
    public final static int DEFAULT_PROTOCOL = 0xFF00;
    public final static int DEFAULT_HEARTBEAT_TIME_FOR_SEPARATE_NW = 575; //   9:35
    public final static int DEFAULT_HEARTBEAT_FOR_SHARED_NW = 10;  // minutes


    public static class AppConfig {
        public String cmdid;
        public String server;
        public int port;
        public int protocol;
        public int networkProtocol;
        public int network; // 0: SIM1 1: SIM2 2: WIFI
        public int heartbeat;
        public int packetSize;
        public int encryption;
    }

    public static class MasterConfig {
        public String server;
        public int port;
        public int mntnMode;
        public int quickHbMode;
        public int usingAbsHbTime;
        public int heartbeat;   // Unit minute
        public int[] absHeartbeats; // second
        public int separateNetwork;

        public String getUrl() {
            if (TextUtils.isEmpty(server)) {
                return "";
            }
            return "http://" + server + ":" + Integer.toString(port);
        }
    }

    public static String readTextFile(String path) {
        FileInputStream fis = null;
        InputStreamReader inputStreamReader = null;
        BufferedReader bufferedReader = null;
        StringBuilder stringBuilder = null;
        try {
            File appCfgFile = new File(path);
            if (appCfgFile.exists()) {
                fis = new FileInputStream(appCfgFile);
                inputStreamReader = new InputStreamReader(fis, "UTF-8");
                bufferedReader = new BufferedReader(inputStreamReader);
                stringBuilder = new StringBuilder();
                String line;
                while ((line = bufferedReader.readLine()) != null) {
                    stringBuilder.append(line);
                }
            }
        } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
        } catch (Exception e) {
                e.printStackTrace();
        } finally {
            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
            if (inputStreamReader != null) {
                try {
                    inputStreamReader.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
            if (fis != null) {
                try {
                    fis.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }

        return stringBuilder == null ? null : stringBuilder.toString();
    }

    public static boolean isAppAlive(Context context, String packageName) {
        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningServiceInfo> services = am.getRunningServices(Integer.MAX_VALUE);

        boolean isRunning = false;
        for (ActivityManager.RunningServiceInfo rsi : services) {
            if (packageName.equalsIgnoreCase(rsi.service.getPackageName())) {
                isRunning = true;
                break;
            }
        }

        return isRunning;
    }

    public static String buildAppDir(Context contxt) {

        String path = Environment.getExternalStorageDirectory().getAbsolutePath();
        if (!path.endsWith(File.separator)) {
            path += File.separator;
        }
        path += contxt.getPackageName() + File.separator;
        File pathFile = new File(path);
        if (!pathFile.exists() && !pathFile.mkdirs()) {
            return null;
        }

        return path;
    }

    public static void removeMpConfigFiles(Context context) {
        String appPath = buildMpAppDir(context);

        File path = new File(appPath + "data/imgparams/");
        if (path.exists() && path.isDirectory()) {
            FileUtils.DeleteFilesInPath(path.getAbsolutePath());
        }

        path = new File(appPath + "data/schedules/");
        if (path.exists() && path.isDirectory()) {
            FileUtils.DeleteFilesInPath(path.getAbsolutePath());
        }

        path = new File(appPath + "data/videoparams/");
        if (path.exists() && path.isDirectory()) {
            FileUtils.DeleteFilesInPath(path.getAbsolutePath());
        }

        path = new File(appPath + "data/sampling");
        if (path.exists() && path.isFile()) {
            path.delete();
        }
    }

    public static String buildMpAppDir(Context contxt) {

        String path = Environment.getExternalStorageDirectory().getAbsolutePath();
        if (!path.endsWith(File.separator)) {
            path += File.separator;
        }

        path += PACKAGE_NAME_MPAPP + File.separator;
        File pathFile = new File(path);
        if (!pathFile.exists() && !pathFile.mkdirs()) {
            return null;
        }

        return path;
    }

    public static String buildMasterAppDir(Context contxt) {

        String path = Environment.getExternalStorageDirectory().getAbsolutePath();
        if (!path.endsWith(File.separator)) {
            path += File.separator;
        }

        path += PACKAGE_NAME_MPMASTER + File.separator;
        File pathFile = new File(path);
        if (!pathFile.exists() && !pathFile.mkdirs()) {
            return null;
        }

        return path;
    }

    public static AppConfig getMpAppConfig(Context context) {

        AppConfig appConfig = new AppConfig();

        String appPath = buildMpAppDir(context);

        try {
            String content = readTextFile(appPath + "data/App.json");

            JSONObject jsonObject = TextUtils.isEmpty(content) ? new JSONObject() : new JSONObject(content);
            appConfig.cmdid = jsonObject.optString(jsonObject.has("cmdid") ? "cmdid" : "CMDID", "");
            appConfig.server = jsonObject.optString(jsonObject.has("server") ? "server" : "Server", "");
            appConfig.port = jsonObject.optInt(jsonObject.has("port") ? "port" : "Port", 0);
            appConfig.protocol = jsonObject.optInt(jsonObject.has("protocol") ? "protocol" : "Protocol", DEFAULT_PROTOCOL);
            appConfig.networkProtocol = jsonObject.optInt(jsonObject.has("networkProtocol") ? "networkProtocol" : "NetworkProtocol", 0);
            appConfig.network = jsonObject.optInt(jsonObject.has("network") ? "network" : "Network", 0);
            appConfig.heartbeat = jsonObject.optInt("heartbeat", 0);
            appConfig.packetSize = jsonObject.optInt("packetSize", 0);
            appConfig.encryption = jsonObject.optInt("encryption", 0);

            if (appConfig.protocol == 0) {
                appConfig.protocol = DEFAULT_PROTOCOL;
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }

        return appConfig;
    }

    public static MasterConfig getMasterConfig(Context context) {

        MasterConfig masterConfig = new MasterConfig();
        String appPath = buildAppDir(context);

        try {
            String content = readTextFile(appPath + "data/Master.json");

            JSONObject jsonObject = TextUtils.isEmpty(content) ? new JSONObject() : new JSONObject(content);
            masterConfig.server = jsonObject.optString("server", "");
            masterConfig.port = jsonObject.optInt("port", 80);
            masterConfig.mntnMode = jsonObject.optInt("mntnMode", 0);
            masterConfig.quickHbMode = jsonObject.optInt("quickHbMode", 0);
            masterConfig.usingAbsHbTime = jsonObject.optInt("usingAbsHbTime", 0);
            masterConfig.separateNetwork = jsonObject.optInt("separateNetwork", 0);
            // long defaultHearbeat = masterConfig.separateNetwork == 0 ? DEFAULT_HEARTBEAT_FOR_SHARED_NW : DEFAULT_HEARTBEAT_FOR_SEPARATE_NW;
            masterConfig.heartbeat = jsonObject.optInt("heartbeat", DEFAULT_HEARTBEAT_FOR_SHARED_NW);
            if (jsonObject.has("absHeartbeats")) {
                JSONArray jsonHbs = jsonObject.getJSONArray("absHeartbeats");
                masterConfig.absHeartbeats = new int[jsonHbs.length()];
                for (int idx = 0; idx < jsonHbs.length(); idx++) {
                    masterConfig.absHeartbeats[idx] = jsonHbs.optInt(idx, 0);
                }
            } else {
                masterConfig.absHeartbeats = new int[1];
                masterConfig.absHeartbeats[0] = DEFAULT_HEARTBEAT_TIME_FOR_SEPARATE_NW;
            }

        } catch (JSONException e) {
            e.printStackTrace();
        }

        return masterConfig;
    }

    public static void saveMasterConfig(Context context, MasterConfig masterConfig) {

        String appPath = buildAppDir(context);
        FileOutputStream fos = null;
        OutputStreamWriter outputStreamWriter = null;
        try {

            File dataPath = new File(appPath + "data/");
            if (!dataPath.exists()) {
                dataPath.mkdirs();
            }

            String path = appPath + "data/Master.json";

            String content = readTextFile(path);

            JSONObject jsonObject = TextUtils.isEmpty(content) ? new JSONObject() : new JSONObject(content);
            jsonObject.put("server", masterConfig.server);
            jsonObject.put("port", masterConfig.port);
            jsonObject.put("mntnMode", masterConfig.mntnMode);
            jsonObject.put("quickHbMode", masterConfig.quickHbMode);
            jsonObject.put("heartbeat", masterConfig.heartbeat);
            jsonObject.put("usingAbsHbTime", masterConfig.usingAbsHbTime);
            jsonObject.put("separateNetwork", masterConfig.separateNetwork);

            JSONArray jsonHbTimes = new JSONArray();
            if (masterConfig.absHeartbeats != null) {
                for (long item : masterConfig.absHeartbeats) {
                    jsonHbTimes.put(jsonHbTimes.length(), item);
                }
            }

            jsonObject.put("absHeartbeats", jsonHbTimes);

            fos = new FileOutputStream(new File(path));
            outputStreamWriter = new OutputStreamWriter(fos, "UTF-8");
            outputStreamWriter.write(jsonObject.toString());
        } catch (IOException e) {
            e.printStackTrace();
        } catch (JSONException e) {
            e.printStackTrace();
        } finally {
            if (outputStreamWriter != null) {
                try {
                    outputStreamWriter.close();
                } catch (Exception ex) {
                }
            }
            if (fos != null) {
                try {
                    fos.close();
                } catch (Exception ex) {
                }
            }
        }
    }

    public static void restartMpApp(Context context) {
        /*
        Context context = MicroPhotoService.this.getApplicationContext();
        Intent intent = getPackageManager().getLaunchIntentForPackage(context.getPackageName());

        int noDelay = 1;
        intent.putExtra("noDelay", noDelay);
        PendingIntent restartIntent = PendingIntent.getActivity(context, 0, intent, 0);
        AlarmManager mgr = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
        mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 1000, restartIntent); // 1秒钟后重启应用
        System.exit(0);

                     */

        restartApp(context, PACKAGE_NAME_MPAPP);
    }

    public static void restartApp(Context context, String packageName) {
        /*
        Context context = MicroPhotoService.this.getApplicationContext();
        Intent intent = getPackageManager().getLaunchIntentForPackage(context.getPackageName());

        int noDelay = 1;
        intent.putExtra("noDelay", noDelay);
        PendingIntent restartIntent = PendingIntent.getActivity(context, 0, intent, 0);
        AlarmManager mgr = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
        mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 1000, restartIntent); // 1秒钟后重启应用
        System.exit(0);

                     */

        try {
            Intent intent = context.getPackageManager().getLaunchIntentForPackage(packageName);
            if (intent != null) {
                intent.putExtra("noDelay", 1);
                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                context.startActivity(intent);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void saveMpAppConfig(Context context, AppConfig appConfig) {
        String appPath = buildMpAppDir(context);

        saveMpAppConfig(appPath, appConfig);
    }

    public static void saveMpAppConfig(String path, AppConfig appConfig) {

        FileOutputStream fos = null;
        OutputStreamWriter outputStreamWriter = null;
        try {

            File dataPath = new File(path + "data/");
            if (!dataPath.exists()) {
                dataPath.mkdirs();
            }

            String content = readTextFile(path + "data/App.json");

            JSONObject jsonObject = TextUtils.isEmpty(content) ? new JSONObject() : new JSONObject(content);
            jsonObject.put("CMDID", appConfig.cmdid);
            jsonObject.put("server", appConfig.server);
            jsonObject.put("port", appConfig.port);
            jsonObject.put("protocol", appConfig.protocol);
            jsonObject.put("networkProtocol", appConfig.networkProtocol);
            jsonObject.put("network", appConfig.network);
            jsonObject.put("encryption", appConfig.encryption);

            if (appConfig.heartbeat > 0) {
                jsonObject.put("heartbeat", appConfig.heartbeat);
            } else {
                jsonObject.remove("heartbeat");
            }
            if (appConfig.packetSize > 0) {
                jsonObject.put("packetSize", appConfig.packetSize);
            } else {
                jsonObject.remove("packetSize");
            }

            fos = new FileOutputStream(new File(path + "data/App.json"));
            outputStreamWriter = new OutputStreamWriter(fos, "UTF-8");
            outputStreamWriter.write(jsonObject.toString());
        } catch (IOException e) {
            e.printStackTrace();
        } catch (JSONException e) {
            e.printStackTrace();
        } finally {
            if (outputStreamWriter != null) {
                try {
                    outputStreamWriter.close();
                } catch (Exception ex) {
                }
            }
            if (fos != null) {
                try {
                    fos.close();
                } catch (Exception ex) {
                }
            }
        }
    }

    public static String getVersionName(Context context) {
        String verName = "";
        try {
            verName = context.getPackageManager().
                    getPackageInfo(context.getPackageName(), 0).versionName;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return verName;
    }

    public static int getVersionCode(Context context) {
        int versionCode = 0;
        try {
            versionCode = context.getPackageManager().
                    getPackageInfo(context.getPackageName(), 0).versionCode;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return versionCode;
    }


}
