/*
 * Copyright 2015 by AVM GmbH <info@avm.de>
 *
 * This software contains free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License ("License") as
 * published by the Free Software Foundation  (version 3 of the License).
 * This software is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the copy of the
 * License you received along with this software for more details.
 */

package de.avm.android.fritzapp.service;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;

import de.avm.android.fritzapp.com.ConnectionProblem;
import de.avm.android.fritzapp.gui.SettingsExtendedActivity;
import de.avm.fundamentals.logger.FileLog;

public class NetworkChangedLegacyHandler extends NetworkChangedHandler
{
    private static final String TAG = "NetworkChangedLegacyH";

    public NetworkChangedLegacyHandler(Context context)
    {
        super(context);
    }

    public void registerCallback(OnNetworkChangedListener listener)
    {
        hasNetworkChanged(); // init members

        mChangedListener = listener;
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
        getContext().registerReceiver(mConnectivityChangeReceiver, intentFilter);
    }

    public void unregisterCallback()
    {
        getContext().unregisterReceiver(mConnectivityChangeReceiver);
        mChangedListener = null;
    }

    public ConnectionProblem checkValidConnectivity()
    {
        ConnectionProblem result = ConnectionProblem.NETWORK_DISCONNECTED;

        NetworkInfo networkInfo = getConnectivityManager().getActiveNetworkInfo();
        if ((networkInfo != null) && networkInfo.isConnectedOrConnecting())
        {
            if (networkInfo.getType() == ConnectivityManager.TYPE_WIFI)
            {
                result = ConnectionProblem.OK;
            }
            else if (SettingsExtendedActivity.isWlanOnly(getContext()))
            {
                if (!((WifiManager)getContext().getSystemService(Context.WIFI_SERVICE))
                        .isWifiEnabled())
                    result = ConnectionProblem.WLAN_OFF;
            }
            else result = ConnectionProblem.OK;
        }

        return result;
    }

    private OnNetworkChangedListener mChangedListener = null;
    private BroadcastReceiver mConnectivityChangeReceiver = new ConnectivityChangeReceiver();
    private Integer mLastCheckedNetworkType = null;
    private String mLastCheckedSsid = null;

    private boolean hasNetworkChanged()
    {
        boolean result = false;

        NetworkInfo info = getConnectivityManager().getActiveNetworkInfo();
        if ((info != null) && info.isConnectedOrConnecting() &&
                ((info.getType() == ConnectivityManager.TYPE_WIFI) ||
                        !SettingsExtendedActivity.isWlanOnly(getContext())))
        {
            if ((mLastCheckedNetworkType == null) ||
                    (info.getType() != mLastCheckedNetworkType))
            {
                result = true;
                mLastCheckedNetworkType = info.getType();
                mLastCheckedSsid = null;
            }
            else if (info.getType() == ConnectivityManager.TYPE_WIFI)
            {
                WifiInfo wifiInfo = ((WifiManager)getContext()
                        .getSystemService(Context.WIFI_SERVICE))
                        .getConnectionInfo();
                result = (mLastCheckedSsid == null) || (wifiInfo == null) ||
                        !mLastCheckedSsid.equals(wifiInfo.getSSID());
                mLastCheckedNetworkType = ConnectivityManager.TYPE_WIFI;
                mLastCheckedSsid = (wifiInfo == null) ? null : wifiInfo.getSSID();
            }
        }
        else
        {
            result = (mLastCheckedNetworkType != null);
            mLastCheckedNetworkType = null;
            mLastCheckedSsid = null;
        }

        return result;
    }

    private class ConnectivityChangeReceiver extends BroadcastReceiver
    {
        public void onReceive(Context context, Intent intent)
        {
            if (DEBUG) FileLog.d(TAG, "onReceive()");
            if ((mChangedListener != null) &&
                    intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION) &&
                    hasNetworkChanged())
            {
                mChangedListener.onChanged(true);
            }
        }
    }
}
