/*
 * Copyright (c) 2015. Ncomz. All Rights Reserved
 */

package com.ntels.kneet.v3.common.mdns;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.AsyncTask;
import android.os.Build;
import android.os.IBinder;
import android.os.SystemClock;
import android.util.Log;

import com.ntels.kneet.v3.common.Constants;
import com.ntels.kneet.v3.common.util.Dlog;
import com.ntels.kneet.v3.common.util.Util;

import java.io.IOException;
import java.lang.reflect.Method;
import java.net.InetAddress;

import javax.jmdns.JmDNS;
import javax.jmdns.ServiceInfo;

public class MdnsRegService extends Service {

    private static final String TAG    = "mDNSService";
    private static       JmDNS  mJmDNS = null;
    private ServiceInfo mServiceInfo;
    Util util = new Util();

    public MdnsRegService() {

    }

    @Override public void onCreate() {

        Log.d("PersistentService", "onCreate");
        unregisterRestartAlarm();                                                 //이미 등록된 알람이 있으면 제거
        super.onCreate();
    }

    @Override public IBinder onBind(Intent intent) {

        Dlog.i(TAG, "onBind()");
        return null;
    }

    @Override public int onStartCommand(Intent intent, int flags, int startId) {

        Dlog.i(TAG, "onStartCommand()");
        try {
            new DoStartBackgroundTask().execute();
        } catch (Exception e) {
            e.printStackTrace();
        }

        //        return super.onStartCommand(intent, flags, startId);
        return START_STICKY;
    }

    @Override public void onDestroy() {
        super.onDestroy();
        try {
            new DoStopBackgroundTask().execute();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private class DoStartBackgroundTask extends AsyncTask<Void, Void, Void> {

        /********************************************************************************************************
         * onPreExecute
         *
         * @param
         *
         * @return
         ********************************************************************************************************/
        @Override protected void onPreExecute() {

            super.onPreExecute();
        }

        /********************************************************************************************************
         * doInBackground
         *
         * @param
         *
         * @return
         ********************************************************************************************************/
        @Override protected Void doInBackground(Void... params) {

            try {

                ConnectivityManager manager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
                NetworkInfo activeNetwork = manager.getActiveNetworkInfo();

                WifiManager myWifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
                WifiInfo myWifiInfo = myWifiManager.getConnectionInfo();
                int ipAddress = myWifiInfo.getIpAddress();
                String sIpAddress = android.text.format.Formatter.formatIpAddress(ipAddress);
                String sSsid = myWifiInfo.getSSID();

                String sOldIpAddress = util.getPreferences(getApplicationContext(), Constants.EXTRA_IP);
                String sOldSsid = util.getPreferences(getApplicationContext(), Constants.EXTRA_SSID);

                if ( null != activeNetwork ) {
                    if ( activeNetwork.getType() == ConnectivityManager.TYPE_WIFI ) {
                        if ( activeNetwork.getState() == NetworkInfo.State.CONNECTED ) {
                            if ( !(sOldSsid.equals(sSsid) && sOldIpAddress.equals(sIpAddress)) ) {
                                Dlog.v("mJmDNS.unregisterService", mServiceInfo);
                                try {
                                    if ( mJmDNS != null ) {
                                        Dlog.v("mJmDNS.unregisterService");
                                        if ( mServiceInfo != null ) {
                                            mJmDNS.unregisterService(mServiceInfo);
                                        }
                                        mJmDNS.close();
                                    } else {
                                        Dlog.v("already closed");
                                    }
                                } catch (Exception e) {
                                } finally {
                                    mJmDNS = null;
                                }

                                System.out.println("WiFi ssid is " + sSsid);
                                System.out.println("WiFi address is " + sIpAddress);

                                byte[] byteaddr = new byte[]{(byte) (ipAddress & 0xff), (byte) (ipAddress >> 8 & 0xff), (byte) (ipAddress >> 16 & 0xff), (byte) (ipAddress >> 24 & 0xff)};

                                // deviceId : android-(16byte)
                                Method getString = Build.class.getDeclaredMethod("getString", String.class);
                                getString.setAccessible(true);
                                String deviceId = getString.invoke(null, "net.hostname").toString();

                                mServiceInfo = ServiceInfo.create("_ntels._tcp.local.", deviceId, 7979, "Service Description...");
                                mJmDNS = JmDNS.create(InetAddress.getByAddress(byteaddr), deviceId);
                                mJmDNS.registerService(mServiceInfo);
                                Dlog.i(TAG, "hostname : " + mJmDNS.getHostName());
                                Dlog.i(TAG, "registerService domain : " + mServiceInfo.getDomain());
                                Dlog.i(TAG, "registerService app : " + mServiceInfo.getApplication());

                                util.setPreferences(getApplicationContext(), Constants.EXTRA_SSID, sSsid);
                                util.setPreferences(getApplicationContext(), Constants.EXTRA_IP, sIpAddress);
                            }
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }

        /********************************************************************************************************
         * onPostExecute
         *
         * @param
         *
         * @return
         ********************************************************************************************************/
        @Override protected void onPostExecute(Void result) {

            super.onPostExecute(result);
        }
    }
    private class DoStopBackgroundTask extends AsyncTask<Void, Void, Void> {

        /********************************************************************************************************
         * onPreExecute
         *
         * @param
         *
         * @return
         ********************************************************************************************************/
        @Override protected void onPreExecute() {

            super.onPreExecute();
        }

        /********************************************************************************************************
         * doInBackground
         *
         * @param
         *
         * @return
         ********************************************************************************************************/
        @Override protected Void doInBackground(Void... params) {

            try {
                registerRestartAlarm();
                if ( mJmDNS != null ) {
                    Log.i(TAG, "before JmDNS closed : " + mJmDNS.getHostName());
                    if ( mServiceInfo != null ) {
                        mJmDNS.unregisterService(mServiceInfo);
                    }
                    Log.i(TAG, "unregisterService : " + mServiceInfo.getDomain());
                    mJmDNS.close();
                    Log.i(TAG, "JmDNS closed : " + mJmDNS.getHostName());
                    mJmDNS = null;
                } else {
                    Log.w(TAG, "JmDNS is null");
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }

        /********************************************************************************************************
         * onPostExecute
         *
         * @param
         *
         * @return
         ********************************************************************************************************/
        @Override protected void onPostExecute(Void result) {

            super.onPostExecute(result);
        }
    }

    public void registerRestartAlarm() {

        util.setPreferences(this, Constants.EXTRA_SSID, "");
        util.setPreferences(this, Constants.EXTRA_IP, "");
        Log.d("PersistentService", "registerRestartAlarm");
        Intent intent = new Intent(this, RestartService.class);
        intent.setAction("ACTION.RESTART.PersistentService");
        PendingIntent sender = PendingIntent.getBroadcast(this, 0, intent, 0);
        long firstTime = SystemClock.elapsedRealtime();
        firstTime += 10 * 1000;                                               // 10초 후에 알람이벤트 발생
        AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
        am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstTime, 10 * 1000, sender);
    }

    public void unregisterRestartAlarm() {

        Log.d("PersistentService", "unregisterRestartAlarm");
        Intent intent = new Intent(this, RestartService.class);
        intent.setAction("ACTION.RESTART.PersistentService");
        PendingIntent sender = PendingIntent.getBroadcast(this, 0, intent, 0);
        AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
        am.cancel(sender);
    }
}
