package org.xbib.io.webdav.client.methods;

import org.xbib.io.webdav.common.FieldValueParser;
import java.net.http.HttpHeaders;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;

/**
 * Represents an HTTP OPTIONS request.
 *
 * @see <a href="http://webdav.org/specs/rfc7231.html#rfc.section.4.3.7">RFC 7231, Section 4.3.7</a>
 */
public class Options extends AbstractMethod {

    private final Set<String> allowedMethods = new HashSet<>();

    private final Set<String> complianceClasses = new HashSet<>();

    private final Set<String> dasl = new HashSet<>();

    public Set<String> getAllowedMethods() {
        return allowedMethods;
    }

    public Set<String> getComplianceClasses() {
        return complianceClasses;
    }

    public Set<String> getDasl() {
        return dasl;
    }

    public String method() {
        return "OPTIONS";
    }

    /**
     * This implementation will parse the <tt>Allow</tt> and <tt>DAV</tt> headers to obtain
     * the set of HTTP methods and WebDAV compliance classes supported by the resource
     * identified by the Request-URI.
     */
    @Override
    public HttpResponse.BodySubscriber<String> apply(HttpResponse.ResponseInfo responseInfo) {
        HttpHeaders httpHeaders = responseInfo.headers();
        Optional<String> optional = httpHeaders.firstValue("Allow");
        if (optional.isPresent()) {
            for (String method : optional.get().split(",")) {
                allowedMethods.add(method.trim().toUpperCase());
            }
        }
        optional = httpHeaders.firstValue("DAV");
        if (optional.isPresent()) {
            for (String s : FieldValueParser.tokenizeList(optional.get())) {
                complianceClasses.add(s.trim());
            }
        }
        optional = httpHeaders.firstValue("DASL");
        if (optional.isPresent()) {
            for (String s : FieldValueParser.tokenizeList(optional.get())) {
                if (s.startsWith("<") && s.endsWith(">")) {
                    s = s.substring(1, s.length() - 1);
                }
                dasl.add(s.trim());
            }
        }
        return HttpResponse.BodySubscribers.ofString(StandardCharsets.UTF_8);
    }
}
