summaryrefslogtreecommitdiff
path: root/app/src/main/java/se/leap/bitmaskclient/eip/GatewaySelector.java
blob: 6a0b4b08e429758d4bc5f500ed9c2c7ea0e8453b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
package se.leap.bitmaskclient.eip;

import static se.leap.bitmaskclient.base.utils.TimezoneHelper.timezoneDistance;
import static se.leap.bitmaskclient.base.utils.TimezoneHelper.getCurrentTimezone;

import android.util.Log;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

public class GatewaySelector {
    private final static String TAG = GatewaySelector.class.getSimpleName();
    List<Gateway> gateways;
    TreeMap<Integer, Set<Gateway>> offsets;

    public GatewaySelector(List<Gateway> gateways) {
        this.gateways = gateways;
        this.offsets = calculateOffsets();
    }

    public ArrayList<Gateway> getGatewaysSortedByDistance() {
        ArrayList<Gateway> list = new ArrayList<>();
        int i = 0;
        for (Collection<Gateway> gatewayCollection : offsets.values()) {
            list.addAll(gatewayCollection);
        }
        return list;
    }

    public Gateway select() {
        return closestGateway();
    }

    public Gateway select(int nClosest) {
        int i = 0;
        for (Map.Entry<Integer,Set<Gateway>> entrySet : offsets.entrySet()) {
            for (Gateway gateway : entrySet.getValue()) {
                if (i == nClosest) {
                    return gateway;
                }
                i = i + 1;
            }
        }

        Log.e(TAG, "There are less than " + (nClosest + 1) + " Gateways available.");
        return null;
    }

    private Gateway closestGateway() {
        return offsets.isEmpty() ? null : offsets.firstEntry().getValue().iterator().next();
    }

    // calculateOffsets randomizes the order of Gateways with the same distance, e.g. from the same location
    private TreeMap<Integer, Set<Gateway>> calculateOffsets() {
        TreeMap<Integer, Set<Gateway>> offsets = new TreeMap<Integer, Set<Gateway>>();
        int localOffset = getCurrentTimezone();
        for (Gateway gateway : gateways) {
            int dist = timezoneDistance(localOffset, gateway.getTimezone());
            Set<Gateway> set = (offsets.get(dist) != null) ?
                    offsets.get(dist) : new HashSet<Gateway>();
            set.add(gateway);
            offsets.put(dist, set);
        }
        return offsets;
    }

}