package io.delphiplatform.api.util;

import org.apache.commons.lang3.StringUtils;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

public class HttpUtils {

    /**
     * Parses {@code paramName} list-of-strings param from raw query string while correctly handling escaped commas
     * inside each individual string within list (spring cannot do it correctly by itself right now)
     *
     * E.g. parses 'genres=Classic%2Cpiano,Pop' into ['Classic,piano', 'Pop']
     * */
    public static Set<String> parseRawStringListQueryParamCommaSafe(String rawQueryParams, String paramName) {
        Set<String> listParamValue = new HashSet<>();

        if (StringUtils.isEmpty(rawQueryParams)) {
            return listParamValue;
        }

        String[] nameValueStrings = rawQueryParams.split("&");
        if (nameValueStrings.length > 0) {
            Arrays.stream(nameValueStrings)
                .filter(nameValueStr -> nameValueStr.startsWith(paramName))
                .map(nameValueStr -> {
                    String[] nameValuePair = nameValueStr.split("=");
                    return nameValuePair.length == 2 ? nameValuePair[1] : null;
                })
                .filter(Objects::nonNull)
                .forEach(valueStr -> {
                    listParamValue.addAll(
                        Arrays.stream(valueStr.split(","))
                            .map(HttpUtils::decodeUrlComponent)
                            .filter(Optional::isPresent)
                            .map(Optional::get)
                            .collect(Collectors.toList())
                    );
                });
        }

        return listParamValue;
    }

    public static Optional<String> decodeUrlComponent(String queryStr) {
        if (StringUtils.isEmpty(queryStr)) {
            return Optional.empty();
        }

        try {
            String decoded = URLDecoder.decode(queryStr, StandardCharsets.UTF_8.name());
            return StringUtils.isEmpty(decoded.trim()) ? Optional.empty() : Optional.of(decoded.trim());
        } catch (UnsupportedEncodingException e) {
            //should not happen
            throw new RuntimeException(e);
        }
    }
}

