/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.wifi;

import android.Manifest.permission;
import android.content.Context;
import android.net.INetworkScoreCache;
import android.net.NetworkKey;
import android.net.ScoredNetwork;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiManager;
import android.util.Log;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class WifiNetworkScoreCache extends INetworkScoreCache.Stub
 {

    // A Network scorer returns a score in the range [-128, +127]
    // We treat the lowest possible score as though there were no score, effectively allowing the
    // scorer to provide an RSSI threshold below which a network should not be used.
    public static int INVALID_NETWORK_SCORE = Byte.MIN_VALUE;

    private static String TAG = "WifiNetworkScoreCache";
    private boolean DBG = true;
    private final Context mContext;

    // The key is of the form "<ssid>"<bssid>
    // TODO: What about SSIDs that can't be encoded as UTF-8?
    private final Map<String, ScoredNetwork> mNetworkCache;

    public WifiNetworkScoreCache(Context context) {
        mContext = context;
        mNetworkCache = new HashMap<String, ScoredNetwork>();
    }

     @Override public final void updateScores(List<android.net.ScoredNetwork> networks) {
        if (networks == null) {
            return;
        }
        Log.e(TAG, "updateScores list size=" + networks.size());

        synchronized(mNetworkCache) {
            for (ScoredNetwork network : networks) {
                String networkKey = buildNetworkKey(network);
                if (networkKey == null) continue;
                mNetworkCache.put(networkKey, network);
            }
        }
     }

     @Override public final void clearScores() {
         synchronized (mNetworkCache) {
             mNetworkCache.clear();
         }
     }

    /**
     * Returns whether there is any score info for the given ScanResult.
     *
     * This includes null-score info, so it should only be used when determining whether to request
     * scores from the network scorer.
     */
    public boolean isScoredNetwork(ScanResult result) {
        return getScoredNetwork(result) != null;
    }

    /**
     * Returns whether there is a non-null score curve for the given ScanResult.
     *
     * A null score curve has special meaning - we should never connect to an ephemeral network if
     * the score curve is null.
     */
    public boolean hasScoreCurve(ScanResult result) {
        ScoredNetwork network = getScoredNetwork(result);
        return network != null && network.rssiCurve != null;
    }

    public int getNetworkScore(ScanResult result) {

        int score = INVALID_NETWORK_SCORE;

        ScoredNetwork network = getScoredNetwork(result);
        if (network != null && network.rssiCurve != null) {
            score = network.rssiCurve.lookupScore(result.level);
            if (DBG) {
                Log.e(TAG, "getNetworkScore found scored network " + network.networkKey
                        + " score " + Integer.toString(score)
                        + " RSSI " + result.level);
            }
        }
        return score;
    }

    public int getNetworkScore(ScanResult result, boolean isActiveNetwork) {

        int score = INVALID_NETWORK_SCORE;

        ScoredNetwork network = getScoredNetwork(result);
        if (network != null && network.rssiCurve != null) {
            score = network.rssiCurve.lookupScore(result.level, isActiveNetwork);
            if (DBG) {
                Log.e(TAG, "getNetworkScore found scored network " + network.networkKey
                        + " score " + Integer.toString(score)
                        + " RSSI " + result.level
                        + " isActiveNetwork " + isActiveNetwork);
            }
        }
        return score;
    }

    private ScoredNetwork getScoredNetwork(ScanResult result) {
        String key = buildNetworkKey(result);
        if (key == null) return null;

        //find it
        synchronized(mNetworkCache) {
            ScoredNetwork network = mNetworkCache.get(key);
            return network;
        }
    }

     private String buildNetworkKey(ScoredNetwork network) {
        if (network.networkKey == null) return null;
        if (network.networkKey.wifiKey == null) return null;
        if (network.networkKey.type == NetworkKey.TYPE_WIFI) {
            String key = network.networkKey.wifiKey.ssid;
            if (key == null) return null;
            if (network.networkKey.wifiKey.bssid != null) {
                key = key + network.networkKey.wifiKey.bssid;
            }
            return key;
        }
        return null;
    }

    private String buildNetworkKey(ScanResult result) {
        if (result.SSID == null) {
            return null;
        }
        StringBuilder key = new StringBuilder("\"");
        key.append(result.SSID);
        key.append("\"");
        if (result.BSSID != null) {
            key.append(result.BSSID);
        }
        return key.toString();
    }

    @Override protected final void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
        mContext.enforceCallingOrSelfPermission(permission.DUMP, TAG);
        writer.println("WifiNetworkScoreCache");
        writer.println("  All score curves:");
        for (Map.Entry<String, ScoredNetwork> entry : mNetworkCache.entrySet()) {
            writer.println("    " + entry.getKey() + ": " + entry.getValue().rssiCurve);
        }
        writer.println("  Current network scores:");
        WifiManager wifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
        for (ScanResult scanResult : wifiManager.getScanResults()) {
            writer.println("    " + buildNetworkKey(scanResult) + ": " + getNetworkScore(scanResult));
        }
    }

}
