/****************************************************************
 * 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.james.jmap.methods.integration.cucumber;

import static org.assertj.core.api.Assertions.assertThat;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.inject.Inject;
import javax.mail.Flags;

import org.apache.commons.io.IOUtils;
import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.client.fluent.Request;
import org.apache.http.client.fluent.Response;
import org.apache.http.client.utils.URIBuilder;
import org.apache.james.jmap.api.access.AccessToken;
import org.apache.james.jmap.model.AttachmentAccessToken;
import org.apache.james.mailbox.model.MailboxConstants;
import org.apache.james.mailbox.model.MailboxPath;

import com.google.common.base.Charsets;
import com.google.common.base.MoreObjects;
import com.google.common.base.Objects;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;

import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;
import cucumber.runtime.java.guice.ScenarioScoped;

@ScenarioScoped
public class DownloadStepdefs {

    private static final String ONE_ATTACHMENT_EML_ATTACHEMENT_BLOB_ID = "4000c5145f633410b80be368c44e1c394bff9437";
    private static final String EXPIRED_ATTACHMENT_TOKEN = "usera@domain.tld_"
            + "2016-06-29T13:41:22.124Z_"
            + "DiZa0O14MjLWrAA8P6MG35Gt5CBp7mt5U1EH/M++rIoZK7nlGJ4dPW0dvZD7h4m3o5b/Yd8DXU5x2x4+s0HOOKzD7X0RMlsU7JHJMNLvTvRGWF/C+MUyC8Zce7DtnRVPEQX2uAZhL2PBABV07Vpa8kH+NxoS9CL955Bc1Obr4G+KN2JorADlocFQA6ElXryF5YS/HPZSvq1MTC6aJIP0ku8WRpRnbwgwJnn26YpcHXcJjbkCBtd9/BhlMV6xNd2hTBkfZmYdoNo+UKBaXWzLxAlbLuxjpxwvDNJfOEyWFPgHDoRvzP+G7KzhVWjanHAHrhF0GilEa/MKpOI1qHBSwA==";
    private static final String INVALID_ATTACHMENT_TOKEN = "usera@domain.tld_"
            + "2015-06-29T13:41:22.124Z_"
            + "DiZa0O14MjLWrAA8P6MG35Gt5CBp7mt5U1EH/M++rIoZK7nlGJ4dPW0dvZD7h4m3o5b/Yd8DXU5x2x4+s0HOOKzD7X0RMlsU7JHJMNLvTvRGWF/C+MUyC8Zce7DtnRVPEQX2uAZhL2PBABV07Vpa8kH+NxoS9CL955Bc1Obr4G+KN2JorADlocFQA6ElXryF5YS/HPZSvq1MTC6aJIP0ku8WRpRnbwgwJnn26YpcHXcJjbkCBtd9/BhlMV6xNd2hTBkfZmYdoNo+UKBaXWzLxAlbLuxjpxwvDNJfOEyWFPgHDoRvzP+G7KzhVWjanHAHrhF0GilEa/MKpOI1qHBSwA==";

    private final UserStepdefs userStepdefs;
    private final MainStepdefs mainStepdefs;
    private HttpResponse response;
    private Multimap<String, String> attachmentsByMessageId;
    private Map<String, String> blobIdByAttachmentId;
    private Map<AttachmentAccessTokenKey, AttachmentAccessToken> attachmentAccessTokens;

    @Inject
    private DownloadStepdefs(MainStepdefs mainStepdefs, UserStepdefs userStepdefs) {
        this.mainStepdefs = mainStepdefs;
        this.userStepdefs = userStepdefs;
        this.attachmentsByMessageId = ArrayListMultimap.create();
        this.blobIdByAttachmentId = new HashMap<>();
        this.attachmentAccessTokens = new HashMap<>();
    }
    
    @Given("^\"([^\"]*)\" mailbox \"([^\"]*)\" contains a message \"([^\"]*)\" with an attachment \"([^\"]*)\"$")
    public void appendMessageWithAttachmentToMailbox(String user, String mailbox, String messageId, String attachmentId) throws Throwable {
        MailboxPath mailboxPath = new MailboxPath(MailboxConstants.USER_NAMESPACE, user, mailbox);

        mainStepdefs.jmapServer.serverProbe().appendMessage(user, mailboxPath,
                ClassLoader.getSystemResourceAsStream("eml/oneAttachment.eml"), new Date(), false, new Flags());
        
        attachmentsByMessageId.put(messageId, attachmentId);
        blobIdByAttachmentId.put(attachmentId, "4000c5145f633410b80be368c44e1c394bff9437");
    }

    @Given("^\"([^\"]*)\" mailbox \"([^\"]*)\" contains a message \"([^\"]*)\" with an inlined attachment \"([^\"]*)\"$")
    public void appendMessageWithInlinedAttachmentToMailbox(String user, String mailbox, String messageId, String attachmentId) throws Throwable {
        MailboxPath mailboxPath = new MailboxPath(MailboxConstants.USER_NAMESPACE, user, mailbox);

        mainStepdefs.jmapServer.serverProbe().appendMessage(user, mailboxPath,
                ClassLoader.getSystemResourceAsStream("eml/oneInlinedImage.eml"), new Date(), false, new Flags());
        
        attachmentsByMessageId.put(messageId, attachmentId);
        // TODO
        //blobIdByAttachmentId.put(attachmentId, "<correctComputedBlobId>");
    }

    @When("^\"([^\"]*)\" checks for the availability of the attachment endpoint$")
    public void optionDownload(String username) throws Throwable {
        AccessToken accessToken = userStepdefs.tokenByUser.get(username);
        URI target = mainStepdefs.baseUri().setPath("/download/" + ONE_ATTACHMENT_EML_ATTACHEMENT_BLOB_ID).build();
        Request request = Request.Options(target);
        if (accessToken != null) {
            request.addHeader("Authorization", accessToken.serialize());
        }
        response = request.execute().returnResponse();
    }

    @When("^\"([^\"]*)\" downloads \"([^\"]*)\"$")
    public void downloads(String username, String attachmentId) throws Throwable {
        String blobId = blobIdByAttachmentId.get(attachmentId);
        URIBuilder uriBuilder = mainStepdefs.baseUri().setPath("/download/" + blobId);
        response = authenticatedDownloadRequest(uriBuilder, blobId, username).execute().returnResponse();
    }

    private Request authenticatedDownloadRequest(URIBuilder uriBuilder, String blobId, String username) throws URISyntaxException {
        AccessToken accessToken = userStepdefs.tokenByUser.get(username);
        AttachmentAccessTokenKey key = new AttachmentAccessTokenKey(username, blobId);
        if (attachmentAccessTokens.containsKey(key)) {
            uriBuilder.addParameter("access_token", attachmentAccessTokens.get(key).serialize());
        }
        Request request = Request.Get(uriBuilder.build());
        if (accessToken != null) {
            request.addHeader("Authorization", accessToken.serialize());
        }
        return request;
    }

    @When("^\"([^\"]*)\" is trusted for attachment \"([^\"]*)\"$")
    public void attachmentAccessTokenFor(String username, String attachmentId) throws Throwable {
        userStepdefs.connectUser(username);
        trustForBlobId(blobIdByAttachmentId.get(attachmentId), username);
    }

    private static class AttachmentAccessTokenKey {

        private String username;
        private String blobId;

        public AttachmentAccessTokenKey(String username, String blobId) {
            this.username = username;
            this.blobId = blobId;
        }

        @Override
        public boolean equals(Object obj) {
            if (obj instanceof AttachmentAccessTokenKey) {
                AttachmentAccessTokenKey other = (AttachmentAccessTokenKey) obj;
                return Objects.equal(username, other.username)
                    && Objects.equal(blobId, other.blobId);
            }
            return false;
        }

        @Override
        public int hashCode() {
            return Objects.hashCode(username, blobId);
        }

        @Override
        public String toString() {
            return MoreObjects
                    .toStringHelper(this)
                    .add("username", username)
                    .add("blobId", blobId)
                    .toString();
        }
    }

    private void trustForBlobId(String blobId, String username) throws Exception {
        Response tokenGenerationResponse = Request.Post(mainStepdefs.baseUri().setPath("/download/" + blobId).build())
            .addHeader("Authorization", userStepdefs.tokenByUser.get(username).serialize())
            .execute();
        String serializedAttachmentAccessToken = tokenGenerationResponse.returnContent().asString();
        attachmentAccessTokens.put(
                new AttachmentAccessTokenKey(username, blobId),
                AttachmentAccessToken.from(
                    serializedAttachmentAccessToken,
                    blobId));
    }

    @When("^\"([^\"]*)\" downloads \"([^\"]*)\" with a valid authentication token but a bad blobId$")
    public void downloadsWithValidToken(String username, String attachmentId) throws Throwable {
        URIBuilder uriBuilder = mainStepdefs.baseUri().setPath("/download/badblobId");
        response = Request.Get(uriBuilder.build())
            .addHeader("Authorization", userStepdefs.tokenByUser.get(username).serialize())
            .execute()
            .returnResponse();
    }

    @When("^\"([^\"]*)\" downloads \"([^\"]*)\" without any authentication token$")
    public void getDownloadWithoutToken(String username, String attachmentId) throws Exception {
        String blobId = blobIdByAttachmentId.get(attachmentId);
        response = Request.Get(mainStepdefs.baseUri().setPath("/download/" + blobId).build())
            .execute()
            .returnResponse();
    }

    @When("^\"([^\"]*)\" downloads \"([^\"]*)\" with an empty authentication token$")
    public void getDownloadWithEmptyToken(String username, String attachmentId) throws Exception {
        String blobId = blobIdByAttachmentId.get(attachmentId);
        response = Request.Get(
                mainStepdefs.baseUri()
                    .setPath("/download/" + blobId)
                    .addParameter("access_token", "")
                    .build())
                .execute()
                .returnResponse();
    }

    @When("^\"([^\"]*)\" downloads \"([^\"]*)\" with a bad authentication token$")
    public void getDownloadWithBadToken(String username, String attachmentId) throws Exception {
        String blobId = blobIdByAttachmentId.get(attachmentId);
        response = Request.Get(
                mainStepdefs.baseUri()
                    .setPath("/download/" + blobId)
                    .addParameter("access_token", "bad")
                    .build())
                .execute()
                .returnResponse();
    }

    @When("^\"([^\"]*)\" downloads \"([^\"]*)\" with an invalid authentication token$")
    public void getDownloadWithUnknownToken(String username, String attachmentId) throws Exception {
        String blobId = blobIdByAttachmentId.get(attachmentId);
        response = Request.Get(
                mainStepdefs.baseUri()
                    .setPath("/download/" + blobId)
                    .addParameter("access_token", INVALID_ATTACHMENT_TOKEN)
                    .build())
                .execute()
                .returnResponse();
    }

    @When("^\"([^\"]*)\" downloads \"([^\"]*)\" without blobId parameter$")
    public void getDownloadWithoutBlobId(String username, String attachmentId) throws Throwable {
        String blobId = blobIdByAttachmentId.get(attachmentId);

        URIBuilder uriBuilder = mainStepdefs.baseUri().setPath("/download/");
        trustForBlobId(blobId, username);
        AttachmentAccessTokenKey key = new AttachmentAccessTokenKey(username, blobId);
        uriBuilder.addParameter("access_token", attachmentAccessTokens.get(key).serialize());
        response = Request.Get(uriBuilder.build())
            .execute()
            .returnResponse();
    }

    @When("^\"([^\"]*)\" downloads \"([^\"]*)\" with wrong blobId$")
    public void getDownloadWithWrongBlobId(String username, String attachmentId) throws Throwable {
        String blobId = blobIdByAttachmentId.get(attachmentId);

        URIBuilder uriBuilder = mainStepdefs.baseUri().setPath("/download/badbadbadbadbadbadbadbadbadbadbadbadbadb");
        trustForBlobId(blobId, username);
        AttachmentAccessTokenKey key = new AttachmentAccessTokenKey(username, blobId);
        uriBuilder.addParameter("access_token", attachmentAccessTokens.get(key).serialize());
        response = Request.Get(uriBuilder.build())
            .execute()
            .returnResponse();
    }

    @When("^\"([^\"]*)\" asks for a token for attachment \"([^\"]*)\"$")
    public void postDownload(String username, String attachmentId) throws Throwable {
        String blobId = blobIdByAttachmentId.get(attachmentId);
        AccessToken accessToken = userStepdefs.tokenByUser.get(username);
        response = Request.Post(mainStepdefs.baseUri().setPath("/download/" + blobId).build())
                .addHeader("Authorization", accessToken.serialize())
                .execute()
                .returnResponse();
    }

    @When("^\"([^\"]*)\" downloads \"([^\"]*)\" with \"([^\"]*)\" name$")
    public void downloadsWithName(String username, String attachmentId, String name) throws Exception {
        String blobId = blobIdByAttachmentId.get(attachmentId);
        URIBuilder uriBuilder = mainStepdefs.baseUri().setPath("/download/" + blobId + "/" + name);
        response = authenticatedDownloadRequest(uriBuilder, blobId, username)
                .execute()
                .returnResponse();
    }

    @When("^\"([^\"]*)\" downloads \"([^\"]*)\" with an expired token$")
    public void getDownloadWithExpiredToken(String username, String attachmentId) throws Exception {
        String blobId = blobIdByAttachmentId.get(attachmentId);
        response = Request.Get(mainStepdefs.baseUri().setPath("/download/" + blobId)
                .addParameter("access_token", EXPIRED_ATTACHMENT_TOKEN)
                .build())
            .execute()
            .returnResponse();
    }

    @Then("^the user should be authorized$")
    public void httpStatusDifferentFromUnauthorized() throws IOException {
        assertThat(response.getStatusLine().getStatusCode()).isIn(200, 404);
    }

    @Then("^the user should not be authorized$")
    public void httpUnauthorizedStatus() throws IOException {
        assertThat(response.getStatusLine().getStatusCode()).isEqualTo(401);
    }

    @Then("^the user should receive a bad request response$")
    public void httpBadRequestStatus() throws IOException {
        assertThat(response.getStatusLine().getStatusCode()).isEqualTo(400);
    }

    @Then("^the user should receive that attachment$")
    public void httpOkStatusAndExpectedContent() throws IOException {
        assertThat(response.getStatusLine().getStatusCode()).isEqualTo(200);
        assertThat(IOUtils.toString(response.getEntity().getContent(), Charsets.UTF_8)).isNotEmpty();
    }

    @Then("^the user should receive a not found response$")
    public void httpNotFoundStatus() throws IOException {
        assertThat(response.getStatusLine().getStatusCode()).isEqualTo(404);
    }

    @Then("^the user should receive an attachment access token$")
    public void accessTokenResponse() throws Throwable {
        assertThat(response.getStatusLine().getStatusCode()).isEqualTo(200);
        assertThat(response.getHeaders("Content-Type")).extracting(Header::toString).containsExactly("Content-Type: text/plain");
        assertThat(IOUtils.toString(response.getEntity().getContent(), Charsets.UTF_8)).isNotEmpty();
    }

    @Then("^the attachment is named \"([^\"]*)\"$")
    public void assertContentDisposition(String name) throws IOException {
        assertThat(response.getHeaders("Content-Disposition")).extracting(Header::toString).containsExactly("Content-Disposition: attachment; filename=\"" + name + "\"");
    }
}
