001package com.github.theholywaffle.teamspeak3.commands.response;
002
003/*
004 * #%L
005 * TeamSpeak 3 Java API
006 * %%
007 * Copyright (C) 2017 Bert De Geyter, Roger Baumgartner
008 * %%
009 * Permission is hereby granted, free of charge, to any person obtaining a copy
010 * of this software and associated documentation files (the "Software"), to deal
011 * in the Software without restriction, including without limitation the rights
012 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
013 * copies of the Software, and to permit persons to whom the Software is
014 * furnished to do so, subject to the following conditions:
015 * 
016 * The above copyright notice and this permission notice shall be included in
017 * all copies or substantial portions of the Software.
018 * 
019 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
020 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
021 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
022 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
023 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
024 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
025 * THE SOFTWARE.
026 * #L%
027 */
028
029import com.github.theholywaffle.teamspeak3.api.wrapper.QueryError;
030import com.github.theholywaffle.teamspeak3.api.wrapper.Wrapper;
031import com.github.theholywaffle.teamspeak3.commands.CommandEncoding;
032
033import java.util.ArrayList;
034import java.util.Collections;
035import java.util.HashMap;
036import java.util.List;
037import java.util.Map;
038
039public class DefaultArrayResponse {
040
041        public static DefaultArrayResponse parse(String rawResponse) {
042                if (rawResponse == null || rawResponse.isEmpty()) return EMPTY;
043
044                String[] rawMaps = rawResponse.split("\\|");
045                List<Wrapper> responses = new ArrayList<>(rawMaps.length);
046                if (rawMaps.length == 0) return new DefaultArrayResponse(responses, rawResponse);
047
048                // First response, just use the parsed map
049                Map<String, String> firstResponse = parseMap(rawMaps[0]);
050                responses.add(new Wrapper(firstResponse));
051
052                // Array response: use "default" values from the first response, then add the parsed map
053                for (int i = 1; i < rawMaps.length; ++i) {
054                        final Map<String, String> responseMap = new HashMap<>(firstResponse);
055                        final Map<String, String> ithResponse = parseMap(rawMaps[i]);
056                        responseMap.putAll(ithResponse);
057
058                        responses.add(new Wrapper(responseMap));
059                }
060
061                return new DefaultArrayResponse(responses, rawResponse);
062        }
063
064        public static QueryError parseError(String rawError) {
065                String error = rawError.substring("error ".length());
066                Map<String, String> errorMap = parseMap(error);
067                return new QueryError(errorMap);
068        }
069
070        private static Map<String, String> parseMap(String rawMap) {
071                if (rawMap == null || rawMap.isEmpty()) return Collections.emptyMap();
072
073                final String[] parameters = rawMap.split(" ");
074                final Map<String, String> map = new HashMap<>(parameters.length);
075
076                for (String param : parameters) {
077                        if (param.isEmpty()) continue;
078                        final int pos = param.indexOf("=");
079
080                        if (pos == -1) {
081                                final String valuelessKey = CommandEncoding.decode(param);
082                                map.put(valuelessKey, "");
083                        } else {
084                                final String key = CommandEncoding.decode(param.substring(0, pos));
085                                final String value = CommandEncoding.decode(param.substring(pos + 1));
086                                map.put(key, value);
087                        }
088                }
089
090                return map;
091        }
092
093        private static final DefaultArrayResponse EMPTY = new DefaultArrayResponse(Collections.emptyList(), "");
094
095        private final List<Wrapper> responses;
096        private final String rawResponse;
097
098        private DefaultArrayResponse(List<Wrapper> responses, String rawResponse) {
099                this.responses = Collections.unmodifiableList(responses);
100                this.rawResponse = rawResponse;
101        }
102
103        public List<Wrapper> getResponses() {
104                return responses;
105        }
106
107        public Wrapper getFirstResponse() {
108                if (responses.isEmpty()) return Wrapper.EMPTY;
109                return responses.get(0);
110        }
111
112        public String getRawResponse() {
113                return rawResponse;
114        }
115
116        @Override
117        public String toString() {
118                return rawResponse;
119        }
120}