1package com.android.hotspot2.omadm;
2
3import java.util.ArrayList;
4import java.util.Collection;
5import java.util.Iterator;
6import java.util.LinkedHashMap;
7import java.util.List;
8import java.util.Map;
9
10public class MultiValueMap<T> {
11    private final Map<String, ArrayList<T>> mMap = new LinkedHashMap<>();
12
13    public void put(String key, T value) {
14        key = key.toLowerCase();
15        ArrayList<T> values = mMap.get(key);
16        if (values == null) {
17            values = new ArrayList<>();
18            mMap.put(key, values);
19        }
20        values.add(value);
21    }
22
23    public T get(String key) {
24        key = key.toLowerCase();
25        List<T> values = mMap.get(key);
26        if (values == null) {
27            return null;
28        } else if (values.size() == 1) {
29            return values.get(0);
30        } else {
31            throw new IllegalArgumentException("Cannot do get on multi-value");
32        }
33    }
34
35    public T replace(String key, T oldValue, T newValue) {
36        key = key.toLowerCase();
37        List<T> values = mMap.get(key);
38        if (values == null) {
39            return null;
40        }
41
42        for (int n = 0; n < values.size(); n++) {
43            T value = values.get(n);
44            if (value == oldValue) {
45                values.set(n, newValue);
46                return value;
47            }
48        }
49        return null;
50    }
51
52    public T remove(String key, T value) {
53        key = key.toLowerCase();
54        List<T> values = mMap.get(key);
55        if (values == null) {
56            return null;
57        }
58
59        T result = null;
60        Iterator<T> valueIterator = values.iterator();
61        while (valueIterator.hasNext()) {
62            if (valueIterator.next() == value) {
63                valueIterator.remove();
64                result = value;
65                break;
66            }
67        }
68        if (values.isEmpty()) {
69            mMap.remove(key);
70        }
71        return result;
72    }
73
74    public T remove(T value) {
75        T result = null;
76        Iterator<Map.Entry<String, ArrayList<T>>> iterator = mMap.entrySet().iterator();
77        while (iterator.hasNext()) {
78            ArrayList<T> values = iterator.next().getValue();
79            Iterator<T> valueIterator = values.iterator();
80            while (valueIterator.hasNext()) {
81                if (valueIterator.next() == value) {
82                    valueIterator.remove();
83                    result = value;
84                    break;
85                }
86            }
87            if (result != null) {
88                if (values.isEmpty()) {
89                    iterator.remove();
90                }
91                break;
92            }
93        }
94        return result;
95    }
96
97    public Collection<T> values() {
98        List<T> allValues = new ArrayList<>(mMap.size());
99        for (List<T> values : mMap.values()) {
100            for (T value : values) {
101                allValues.add(value);
102            }
103        }
104        return allValues;
105    }
106
107    public T getSingletonValue() {
108        if (mMap.size() != 1) {
109            throw new IllegalArgumentException("Map is not a single entry map");
110        }
111        List<T> values = mMap.values().iterator().next();
112        if (values.size() != 1) {
113            throw new IllegalArgumentException("Map is not a single entry map");
114        }
115        return values.iterator().next();
116    }
117}
118