/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements. See the NOTICE file distributed with this
 * work for additional information regarding copyright ownership. The ASF
 * licenses this file to You under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package org.apache.sling.testing.clients;

import org.apache.http.*;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.params.HttpParams;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.util.*;
import java.util.regex.Pattern;

public class SlingHttpResponse implements CloseableHttpResponse {

    public static final String STATUS = "Status";
    public static final String MESSAGE = "Message";
    public static final String LOCATION = "Location";
    public static final String PARENT_LOCATION = "ParentLocation";
    public static final String PATH = "Path";
    public static final String REFERER = "Referer";
    public static final String CHANGE_LOG = "ChangeLog";

    private final CloseableHttpResponse httpResponse;
    private String content;

    public SlingHttpResponse(CloseableHttpResponse response) {
        this.httpResponse = response;
    }

    /**
     * <p>Get the {@code String} content of the response.</p>
     * <p>The content is cached so it is safe to call this method several times.</p>
     * <p><b>Attention!</b> Calling this method consumes the entity, so it cannot be used as an InputStream later</p>
     *
     * @return the content as String
     */
    public String getContent() {
        if (!this.isConsumed()) {
            try {
                this.content = EntityUtils.toString(this.getEntity());
                this.close();
            } catch (IOException e) {
                throw new RuntimeException("Could not read content from response", e);
            }
        }

        return content;
    }

    public boolean isConsumed() {
        return this.content != null || this.getEntity() == null;
    }

    /**
     * <p>Assert that response matches supplied status</p>
     *
     * @param expected the expected http status
     * @throws ClientException if the response does not match the expected
     */
    public void checkStatus(int expected) throws ClientException {
        if (this.getStatusLine().getStatusCode() != expected) {
            throw new ClientException(this + " has wrong response status ("
                    + this.getStatusLine().getStatusCode() + "). Expected " + expected);
        }
    }

    /**
     * <p>Assert that response matches supplied content type (from Content-Type header)</p>
     *
     * @param expected the expected content type
     * @throws ClientException if the response content type does not match the expected
     */
    public void checkContentType(String expected) throws ClientException {
        // Remove whatever follows semicolon in content-type
        String contentType = this.getEntity().getContentType().getValue();
        if (contentType != null) {
            contentType = contentType.split(";")[0].trim();
        }

        // check for match
        if (!contentType.equals(expected)) {
            throw new ClientException(this + " has wrong content type (" + contentType + "). Expected " + expected);
        }
    }

    /**
     * <p>For each regular expression, assert that at least one line of the response matches the expression</p>
     * <p>The regular expressions are automatically prefixed and suffixed with .* it order to partial-match the lines</p>
     *
     * @param regexp list of regular expressions
     * @throws ClientException if the response content does not match one of the regexp
     */
    public void checkContentRegexp(String... regexp) throws ClientException {
        for(String expr : regexp) {
            final Pattern p = Pattern.compile(".*" + expr + ".*");
            final Scanner scanner = new Scanner(this.getContent());
            boolean matched = false;
            while (scanner.hasNextLine()) {
                String line = scanner.nextLine();
                if (p.matcher(line).matches()) {
                    matched = true;
                    break;
                }
            }

            if (!matched) {
                throw new ClientException("Pattern " + p + " didn't match any line in content");
            }
        }
    }

    /**
     * <p>Assert that all the provided {@code Strings} are contained in the response</p>
     *
     * @param expected list of expected strings
     * @throws ClientException @throws ClientException if the response content does not match one of the strings
     */
    public void checkContentContains(String... expected) throws ClientException {
        for (String s : expected) {
            if (!this.getContent().contains(s)) {
                throw new ClientException("Content does not contain string " + s + ". Content is: \n\n" + getContent());
            }
        }
    }

    /**
     * Get status from Sling Response
     *
     * @return Sling Status
     */
    public String getSlingStatus() {
        String searchPattern = "id=\"" + STATUS + "\">";
        return extractFromHTMLResponse(searchPattern);
    }

    /**
     * Get status from Sling Response as integer
     *
     * @return Sling Status
     * @throws NumberFormatException if sling status can't be parsed as a number
     */
    public int getSlingStatusAsInt() throws NumberFormatException {
        String strStatus = getSlingStatus();
        return Integer.parseInt(strStatus);
    }

    /**
     * Get message from Sling Response
     *
     * @return Sling Message
     */
    public String getSlingMessage() {
        String searchPattern = "id=\"" + MESSAGE + "\">";
        return extractFromHTMLResponse(searchPattern);
    }

    /**
     * Get copy paths from message
     *
     * @return copy paths as String Array
     */
    public String[] getSlingCopyPaths() {
        String copyPaths = getSlingMessage();
        StringTokenizer tokenizer = new StringTokenizer(copyPaths);
        List<String> copies = new ArrayList<String>();
        while (tokenizer.hasMoreElements()) {
            copies.add(tokenizer.nextToken());
        }
        return copies.toArray(new String[copies.size()]);
    }

    /**
     * Get location from Sling Response
     *
     * @return Sling Location
     */
    public String getSlingLocation() {
        String searchPattern = "id=\"" + LOCATION + "\">";
        return extractFromHTMLResponse(searchPattern);
    }

    /**
     * Get parent location from Sling Response
     *
     * @return Sling Parent Location
     */
    public String getSlingParentLocation() {
        String searchPattern = "id=\"" + PARENT_LOCATION + "\">";
        return extractFromHTMLResponse(searchPattern);
    }

    /**
     * Get path from Sling Response
     *
     * @return Sling Path
     */
    public String getSlingPath() {
        String searchPattern = "id=\"" + PATH + "\">";
        return extractFromHTMLResponse(searchPattern);
    }

    /**
     * Get referer from Sling Response
     *
     * @return Sling Referer
     */
    public String getSlingReferer() {
        String searchPattern = "id=\"" + REFERER + "\">";
        return extractFromHTMLResponse(searchPattern);
    }

    /**
     * Get change log from Sling Response
     *
     * @return Sling Change Log
     */
    public String getSlingChangeLog() {
        String searchPattern = "id=\"" + CHANGE_LOG + "\">";
        return extractFromHTMLResponse(searchPattern);
    }

    /**
     * Extract information from response
     *
     * @param searchPattern search pattern to look for
     * @return Sling information
     */
    protected String extractFromHTMLResponse(String searchPattern) {
        String tmpResponse = null;
        int start = getContent().indexOf(searchPattern);
        if (start > 0) {
            start += searchPattern.length();
            tmpResponse = getContent().substring(start);
            int end = tmpResponse.indexOf("<");
            tmpResponse = tmpResponse.substring(0, end);
        }
        return tmpResponse;
    }

    // HttpResponse delegated methods

    @Override
    public StatusLine getStatusLine() {
        return httpResponse.getStatusLine();
    }

    @Override
    public void setStatusLine(StatusLine statusline) {
        httpResponse.setStatusLine(statusline);
    }

    @Override
    public void setStatusLine(ProtocolVersion ver, int code) {
        httpResponse.setStatusLine(ver, code);
    }

    @Override
    public void setStatusLine(ProtocolVersion ver, int code, String reason) {
        httpResponse.setStatusLine(ver, code, reason);
    }

    @Override
    public void setStatusCode(int code) throws IllegalStateException {
        httpResponse.setStatusCode(code);
    }

    @Override
    public void setReasonPhrase(String reason) throws IllegalStateException {
        httpResponse.setReasonPhrase(reason);
    }

    @Override
    public HttpEntity getEntity() {
        return httpResponse.getEntity();
    }

    @Override
    public void setEntity(HttpEntity entity) {
        httpResponse.setEntity(entity);
    }

    @Override
    public Locale getLocale() {
        return httpResponse.getLocale();
    }

    @Override
    public void setLocale(Locale loc) {
        httpResponse.setLocale(loc);
    }

    @Override
    public ProtocolVersion getProtocolVersion() {
        return httpResponse.getProtocolVersion();
    }

    @Override
    public boolean containsHeader(String name) {
        return httpResponse.containsHeader(name);
    }

    @Override
    public Header[] getHeaders(String name) {
        return httpResponse.getHeaders(name);
    }

    @Override
    public Header getFirstHeader(String name) {
        return httpResponse.getFirstHeader(name);
    }

    @Override
    public Header getLastHeader(String name) {
        return httpResponse.getLastHeader(name);
    }

    @Override
    public Header[] getAllHeaders() {
        return httpResponse.getAllHeaders();
    }

    @Override
    public void addHeader(Header header) {
        httpResponse.addHeader(header);
    }

    @Override
    public void addHeader(String name, String value) {
        httpResponse.addHeader(name, value);
    }

    @Override
    public void setHeader(Header header) {
        httpResponse.setHeader(header);
    }

    @Override
    public void setHeader(String name, String value) {
        httpResponse.setHeader(name, value);
    }

    @Override
    public void setHeaders(Header[] headers) {
        httpResponse.setHeaders(headers);
    }

    @Override
    public void removeHeader(Header header) {
        httpResponse.removeHeader(header);
    }

    @Override
    public void removeHeaders(String name) {
        httpResponse.removeHeaders(name);
    }

    @Override
    public HeaderIterator headerIterator() {
        return httpResponse.headerIterator();
    }

    @Override
    public HeaderIterator headerIterator(String name) {
        return httpResponse.headerIterator(name);
    }

    @SuppressWarnings("deprecation")
    @Override
    public HttpParams getParams() {
        return httpResponse.getParams();
    }

    @SuppressWarnings("deprecation")
    @Override
    public void setParams(HttpParams params) {
        httpResponse.setParams(params);
    }

    @Override
    public void close() throws IOException {
        httpResponse.close();
    }
}
