/*
 * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
import com.sun.net.httpserver.HttpsServer;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UncheckedIOException;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpHeaders;
import java.net.http.HttpRequest;
import java.net.http.HttpRequest.BodyPublishers;
import java.net.http.HttpResponse;
import java.net.http.HttpResponse.BodyHandler;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import javax.net.ssl.SSLContext;
import jdk.test.lib.net.SimpleSSLContext;
import jdk.test.lib.util.FileUtils;
import jdk.httpclient.test.lib.common.HttpServerAdapters;
import jdk.httpclient.test.lib.common.TestServerConfigurator;
import jdk.httpclient.test.lib.http2.Http2TestServer;
import jdk.httpclient.test.lib.http2.Http2TestExchange;
import jdk.httpclient.test.lib.http2.Http2Handler;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import static java.lang.System.out;
import static java.net.http.HttpResponse.BodyHandlers.ofFileDownload;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.nio.file.StandardOpenOption.*;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;

/*
 * @test
 * @summary Basic test for ofFileDownload
 * @bug 8196965 8302475
 * @library /test/lib /test/jdk/java/net/httpclient/lib
 * @build jdk.httpclient.test.lib.http2.Http2TestServer jdk.test.lib.net.SimpleSSLContext
 *        jdk.test.lib.Platform jdk.test.lib.util.FileUtils
 *        jdk.httpclient.test.lib.common.TestServerConfigurator
 * @run testng/othervm AsFileDownloadTest
 */
public class AsFileDownloadTest {

    SSLContext sslContext;
    HttpServer httpTestServer;         // HTTP/1.1    [ 4 servers ]
    HttpsServer httpsTestServer;       // HTTPS/1.1
    Http2TestServer http2TestServer;   // HTTP/2 ( h2c )
    Http2TestServer https2TestServer;  // HTTP/2 ( h2  )
    String httpURI;
    String httpsURI;
    String http2URI;
    String https2URI;
    final ReferenceTracker TRACKER = ReferenceTracker.INSTANCE;

    Path tempDir;

    static final String[][] contentDispositionValues = new String[][] {
          // URI query     Content-Type header value         Expected filename
            { "001", "Attachment; filename=example001.html", "example001.html" },
            { "002", "attachment; filename=example002.html", "example002.html" },
            { "003", "ATTACHMENT; filename=example003.html", "example003.html" },
            { "004", "attAChment; filename=example004.html", "example004.html" },
            { "005", "attachmeNt; filename=example005.html", "example005.html" },

            { "006", "attachment; Filename=example006.html", "example006.html" },
            { "007", "attachment; FILENAME=example007.html", "example007.html" },
            { "008", "attachment; fileName=example008.html", "example008.html" },
            { "009", "attachment; fIlEnAMe=example009.html", "example009.html" },

            { "010", "attachment; filename=Example010.html", "Example010.html" },
            { "011", "attachment; filename=EXAMPLE011.html", "EXAMPLE011.html" },
            { "012", "attachment; filename=eXample012.html", "eXample012.html" },
            { "013", "attachment; filename=example013.HTML", "example013.HTML" },
            { "014", "attachment; filename  =eXaMpLe014.HtMl", "eXaMpLe014.HtMl"},

            { "015", "attachment; filename=a",               "a"               },
            { "016", "attachment; filename= b",              "b"               },
            { "017", "attachment; filename=  c",             "c"               },
            { "018", "attachment; filename=    d",           "d"               },
            { "019", "attachment; filename=e  ; filename*=utf-8''eee.txt",  "e"},
            { "020", "attachment; filename*=utf-8''fff.txt; filename=f",    "f"},
            { "021", "attachment;  filename=g",              "g"               },
            { "022", "attachment;   filename= h",            "h"               },

            { "023", "attachment; filename=\"space name\"",                       "space name" },
            { "024", "attachment; filename=me.txt; filename*=utf-8''you.txt",     "me.txt"     },
            { "025", "attachment; filename=\"m y.txt\"; filename*=utf-8''you.txt", "m y.txt"   },

            { "030", "attachment; filename=\"foo/file1.txt\"",        "file1.txt" },
            { "031", "attachment; filename=\"foo/bar/file2.txt\"",    "file2.txt" },
            { "032", "attachment; filename=\"baz\\\\file3.txt\"",       "file3.txt" },
            { "033", "attachment; filename=\"baz\\\\bar\\\\file4.txt\"",  "file4.txt" },
            { "034", "attachment; filename=\"x/y\\\\file5.txt\"",       "file5.txt" },
            { "035", "attachment; filename=\"x/y\\\\file6.txt\"",       "file6.txt" },
            { "036", "attachment; filename=\"x/y\\\\z/file7.txt\"",     "file7.txt" },
            { "037", "attachment; filename=\"x/y\\\\z/\\\\x/file8.txt\"", "file8.txt" },
            { "038", "attachment; filename=\"/root/file9.txt\"",      "file9.txt" },
            { "039", "attachment; filename=\"../file10.txt\"",        "file10.txt" },
            { "040", "attachment; filename=\"..\\\\file11.txt\"",       "file11.txt" },
            { "041", "attachment; filename=\"foo/../../file12.txt\"", "file12.txt" },
    };

    @DataProvider(name = "positive")
    public Object[][] positive() {
        List<Object[]> list = new ArrayList<>();

        Arrays.asList(contentDispositionValues).stream()
                .map(e -> new Object[] {httpURI +  "?" + e[0], e[1], e[2]})
                .forEach(list::add);
        Arrays.asList(contentDispositionValues).stream()
                .map(e -> new Object[] {httpsURI +  "?" + e[0], e[1], e[2]})
                .forEach(list::add);
        Arrays.asList(contentDispositionValues).stream()
                .map(e -> new Object[] {http2URI +  "?" + e[0], e[1], e[2]})
                .forEach(list::add);
        Arrays.asList(contentDispositionValues).stream()
                .map(e -> new Object[] {https2URI +  "?" + e[0], e[1], e[2]})
                .forEach(list::add);

        return list.stream().toArray(Object[][]::new);
    }

    @Test(dataProvider = "positive")
    void test(String uriString, String contentDispositionValue, String expectedFilename)
        throws Exception
    {
        out.printf("test(%s, %s, %s): starting", uriString, contentDispositionValue, expectedFilename);
        HttpClient client = HttpClient.newBuilder().sslContext(sslContext).build();
        TRACKER.track(client);
        ReferenceQueue<HttpClient> queue = new ReferenceQueue<>();
        WeakReference<HttpClient> ref = new WeakReference<>(client, queue);
        try {
            URI uri = URI.create(uriString);
            HttpRequest request = HttpRequest.newBuilder(uri)
                    .POST(BodyPublishers.ofString("May the luck of the Irish be with you!"))
                    .build();

            BodyHandler bh = ofFileDownload(tempDir.resolve(uri.getPath().substring(1)),
                    CREATE, TRUNCATE_EXISTING, WRITE);
            HttpResponse<Path> response = client.send(request, bh);
            Path body = response.body();
            out.println("Got response: " + response);
            out.println("Got body Path: " + body);
            String fileContents = new String(Files.readAllBytes(response.body()), UTF_8);
            out.println("Got body: " + fileContents);

            assertEquals(response.statusCode(), 200);
            assertEquals(body.getFileName().toString(), expectedFilename);
            assertTrue(response.headers().firstValue("Content-Disposition").isPresent());
            assertEquals(response.headers().firstValue("Content-Disposition").get(),
                    contentDispositionValue);
            assertEquals(fileContents, "May the luck of the Irish be with you!");

            if (!body.toAbsolutePath().startsWith(tempDir.toAbsolutePath())) {
                System.out.println("Tempdir = " + tempDir.toAbsolutePath());
                System.out.println("body = " + body.toAbsolutePath());
                throw new AssertionError("body in wrong location");
            }
            // additional checks unrelated to file download
            caseInsensitivityOfHeaders(request.headers());
            caseInsensitivityOfHeaders(response.headers());
        } finally {
            client = null;
            System.gc();
            while (!ref.refersTo(null)) {
                System.gc();
                if (queue.remove(100) == ref) break;
            }
            AssertionError failed = TRACKER.checkShutdown(1000);
            if (failed != null) throw failed;
        }
    }

    // --- Negative

    static final String[][] contentDispositionBADValues = new String[][] {
            // URI query     Content-Type header value
            { "100", ""                                    },  // empty
            { "101", "filename=example.html"               },  // no attachment
            { "102", "attachment; filename=space name"     },  // unquoted with space
            { "103", "attachment; filename="               },  // empty filename param
            { "104", "attachment; filename=\""             },  // single quote
            { "105", "attachment; filename=\"\""           },  // empty quoted
            { "106", "attachment; filename=."              },  // dot
            { "107", "attachment; filename=.."             },  // dot dot
            { "108", "attachment; filename=\".."           },  // badly quoted dot dot
            { "109", "attachment; filename=\"..\""         },  // quoted dot dot
            { "110", "attachment; filename=\"bad"          },  // badly quoted
            { "111", "attachment; filename=\"bad;"         },  // badly quoted with ';'
            { "112", "attachment; filename=\"bad ;"        },  // badly quoted with ' ;'
            { "113", "attachment; filename*=utf-8''xx.txt "},  // no "filename" param

            { "120", "<<NOT_PRESENT>>"                     },  // header not present

    };

    @DataProvider(name = "negative")
    public Object[][] negative() {
        List<Object[]> list = new ArrayList<>();

        Arrays.asList(contentDispositionBADValues).stream()
                .map(e -> new Object[] {httpURI +  "?" + e[0], e[1]})
                .forEach(list::add);
        Arrays.asList(contentDispositionBADValues).stream()
                .map(e -> new Object[] {httpsURI +  "?" + e[0], e[1]})
                .forEach(list::add);
        Arrays.asList(contentDispositionBADValues).stream()
                .map(e -> new Object[] {http2URI +  "?" + e[0], e[1]})
                .forEach(list::add);
        Arrays.asList(contentDispositionBADValues).stream()
                .map(e -> new Object[] {https2URI +  "?" + e[0], e[1]})
                .forEach(list::add);

        return list.stream().toArray(Object[][]::new);
    }

    @Test(dataProvider = "negative")
    void negativeTest(String uriString, String contentDispositionValue)
            throws Exception
    {
        out.printf("negativeTest(%s, %s): starting", uriString, contentDispositionValue);
        HttpClient client = HttpClient.newBuilder().sslContext(sslContext).build();
        TRACKER.track(client);
        ReferenceQueue<HttpClient> queue = new ReferenceQueue<>();
        WeakReference<HttpClient> ref = new WeakReference<>(client, queue);

        try {
            URI uri = URI.create(uriString);
            HttpRequest request = HttpRequest.newBuilder(uri)
                    .POST(BodyPublishers.ofString("Does not matter"))
                    .build();

            BodyHandler bh = ofFileDownload(tempDir, CREATE, TRUNCATE_EXISTING, WRITE);
            try {
                HttpResponse<Path> response = client.send(request, bh);
                fail("UNEXPECTED response: " + response + ", path:" + response.body());
            } catch (UncheckedIOException | IOException ioe) {
                System.out.println("Caught expected: " + ioe);
            }
        } finally {
            client = null;
            System.gc();
            while (!ref.refersTo(null)) {
                System.gc();
                if (queue.remove(100) == ref) break;
            }
            AssertionError failed = TRACKER.checkShutdown(1000);
            if (failed != null) throw failed;
        }
    }

    // -- Infrastructure

    static String serverAuthority(HttpServer server) {
        final String hostIP = InetAddress.getLoopbackAddress().getHostAddress();
        // escape for ipv6
        final String h = hostIP.contains(":") ? "[" + hostIP + "]" : hostIP;
        return h + ":" + server.getAddress().getPort();
    }

    @BeforeTest
    public void setup() throws Exception {
        tempDir = Paths.get("asFileDownloadTest.tmp.dir");
        if (Files.exists(tempDir))
            throw new AssertionError("Unexpected test work dir existence: " + tempDir.toString());

        Files.createDirectory(tempDir);
        // Unique dirs per test run, based on the URI path
        Files.createDirectories(tempDir.resolve("http1/afdt/"));
        Files.createDirectories(tempDir.resolve("https1/afdt/"));
        Files.createDirectories(tempDir.resolve("http2/afdt/"));
        Files.createDirectories(tempDir.resolve("https2/afdt/"));

        // HTTP/1.1 server logging in case of security exceptions ( uncomment if needed )
        //Logger logger = Logger.getLogger("com.sun.net.httpserver");
        //ConsoleHandler ch = new ConsoleHandler();
        //logger.setLevel(Level.ALL);
        //ch.setLevel(Level.ALL);
        //logger.addHandler(ch);

        sslContext = new SimpleSSLContext().get();
        if (sslContext == null)
            throw new AssertionError("Unexpected null sslContext");

        InetSocketAddress sa = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0);
        httpTestServer = HttpServer.create(sa, 0);
        httpTestServer.createContext("/http1/afdt", new Http1FileDispoHandler());
        httpURI = "http://" + serverAuthority(httpTestServer) + "/http1/afdt";

        httpsTestServer = HttpsServer.create(sa, 0);
        httpsTestServer.setHttpsConfigurator(new TestServerConfigurator(sa.getAddress(), sslContext));
        httpsTestServer.createContext("/https1/afdt", new Http1FileDispoHandler());
        httpsURI = "https://" + serverAuthority(httpsTestServer) + "/https1/afdt";

        http2TestServer = new Http2TestServer("localhost", false, 0);
        http2TestServer.addHandler(new Http2FileDispoHandler(), "/http2/afdt");
        http2URI = "http://" + http2TestServer.serverAuthority() + "/http2/afdt";

        https2TestServer = new Http2TestServer("localhost", true, sslContext);
        https2TestServer.addHandler(new Http2FileDispoHandler(), "/https2/afdt");
        https2URI = "https://" + https2TestServer.serverAuthority() + "/https2/afdt";

        httpTestServer.start();
        httpsTestServer.start();
        http2TestServer.start();
        https2TestServer.start();
    }

    @AfterTest
    public void teardown() throws Exception {
        httpTestServer.stop(0);
        httpsTestServer.stop(0);
        http2TestServer.stop();
        https2TestServer.stop();

        if (Files.exists(tempDir)) {
            // clean up
            FileUtils.deleteFileTreeWithRetry(tempDir);
        }
    }

    static String contentDispositionValueFromURI(URI uri) {
        String queryIndex = uri.getQuery();
        String[][] values;
        if (queryIndex.startsWith("0"))  // positive tests start with '0'
            values = contentDispositionValues;
        else if (queryIndex.startsWith("1"))  // negative tests start with '1'
            values = contentDispositionBADValues;
        else
            throw new AssertionError("SERVER: UNEXPECTED query:" + queryIndex);

        return Arrays.asList(values).stream()
                .filter(e -> e[0].equals(queryIndex))
                .map(e -> e[1])
                .findFirst()
                .orElseThrow();
    }

    static class Http1FileDispoHandler implements HttpHandler {
        @Override
        public void handle(HttpExchange t) throws IOException {
            try (InputStream is = t.getRequestBody();
                 OutputStream os = t.getResponseBody()) {
                byte[] bytes = is.readAllBytes();

                String value = contentDispositionValueFromURI(t.getRequestURI());
                if (!value.equals("<<NOT_PRESENT>>"))
                    t.getResponseHeaders().set("Content-Disposition", value);

                t.sendResponseHeaders(200, bytes.length);
                os.write(bytes);
            }
        }
    }

    static class Http2FileDispoHandler implements Http2Handler {
        @Override
        public void handle(Http2TestExchange t) throws IOException {
            try (InputStream is = t.getRequestBody();
                 OutputStream os = t.getResponseBody()) {
                byte[] bytes = is.readAllBytes();

                String value = contentDispositionValueFromURI(t.getRequestURI());
                if (!value.equals("<<NOT_PRESENT>>"))
                    t.getResponseHeaders().addHeader("Content-Disposition", value);

                t.sendResponseHeaders(200, bytes.length);
                os.write(bytes);
            }
        }
    }

    // ---

    // Asserts case-insensitivity of headers (nothing to do with file
    // download, just convenient as we have a couple of header instances. )
    static void caseInsensitivityOfHeaders(HttpHeaders headers) {
        try {
            for (Map.Entry<String, List<String>> entry : headers.map().entrySet()) {
                String headerName = entry.getKey();
                List<String> headerValue = entry.getValue();

                for (String name : List.of(headerName.toUpperCase(Locale.ROOT),
                                           headerName.toLowerCase(Locale.ROOT))) {
                    assertTrue(headers.firstValue(name).isPresent());
                    assertEquals(headers.firstValue(name).get(), headerValue.get(0));
                    assertEquals(headers.allValues(name).size(), headerValue.size());
                    assertEquals(headers.allValues(name), headerValue);
                    assertEquals(headers.map().get(name).size(), headerValue.size());
                    assertEquals(headers.map().get(name), headerValue);
                }
            }
        } catch (Throwable t) {
            System.out.println("failure in caseInsensitivityOfHeaders with:" + headers);
            throw t;
        }
    }
}
