/*
 * ====================================================================
 * 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.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 */

package org.apache.hc.client5.http.entity.mime;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.Writer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;

import org.apache.hc.core5.http.ContentType;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

public class TestMultipartMixed {

    private File tmpfile;

    @AfterEach
    public void cleanup() {
        if (tmpfile != null) {
            tmpfile.delete();
        }
    }

    @Test
    public void testMultipartPartStringParts() throws Exception {
        final MultipartPart p1 = MultipartPartBuilder.create(
                new StringBody("this stuff", ContentType.DEFAULT_TEXT)).build();
        final MultipartPart p2 = MultipartPartBuilder.create(
                new StringBody("that stuff", ContentType.create(
                        ContentType.TEXT_PLAIN.getMimeType(), StandardCharsets.ISO_8859_1))).build();
        final MultipartPart p3 = MultipartPartBuilder.create(
                new StringBody("all kind of stuff", ContentType.DEFAULT_TEXT)).build();
        final HttpStrictMultipart multipart = new HttpStrictMultipart(null, "foo",
                Arrays.asList(p1, p2, p3));

        final ByteArrayOutputStream out = new ByteArrayOutputStream();
        multipart.writeTo(out);
        out.close();

        final String expected =
            "--foo\r\n" +
            "Content-Type: text/plain; charset=UTF-8\r\n" +
            "\r\n" +
            "this stuff\r\n" +
            "--foo\r\n" +
            "Content-Type: text/plain; charset=ISO-8859-1\r\n" +
            "\r\n" +
            "that stuff\r\n" +
            "--foo\r\n" +
            "Content-Type: text/plain; charset=UTF-8\r\n" +
            "\r\n" +
            "all kind of stuff\r\n" +
            "--foo--\r\n";
        final String s = out.toString("US-ASCII");
        Assertions.assertEquals(expected, s);
        Assertions.assertEquals(s.length(), multipart.getTotalLength());
    }

    @Test
    public void testMultipartPartCustomContentType() throws Exception {
        final MultipartPart p1 = MultipartPartBuilder.create(
                new StringBody("this stuff", ContentType.DEFAULT_TEXT)).build();
        final MultipartPart p2 = MultipartPartBuilder.create(
                new StringBody("that stuff", ContentType.parse("stuff/plain; param=value"))).build();
        final HttpStrictMultipart multipart = new HttpStrictMultipart(null, "foo",
                Arrays.asList(p1, p2));

        final ByteArrayOutputStream out = new ByteArrayOutputStream();
        multipart.writeTo(out);
        out.close();

        final String expected =
                "--foo\r\n" +
                        "Content-Type: text/plain; charset=UTF-8\r\n" +
                        "\r\n" +
                        "this stuff\r\n" +
                        "--foo\r\n" +
                        "Content-Type: stuff/plain; param=value\r\n" +
                        "\r\n" +
                        "that stuff\r\n" +
                        "--foo--\r\n";
        final String s = out.toString("US-ASCII");
        Assertions.assertEquals(expected, s);
        Assertions.assertEquals(s.length(), multipart.getTotalLength());
    }

    @Test
    public void testMultipartPartBinaryParts() throws Exception {
        tmpfile = File.createTempFile("tmp", ".bin");
        try (Writer writer = new FileWriter(tmpfile)) {
            writer.append("some random whatever");
        }

        final MultipartPart p1 = MultipartPartBuilder.create(
                new FileBody(tmpfile)).build();
        @SuppressWarnings("resource")
        final MultipartPart p2 = MultipartPartBuilder.create(
                new InputStreamBody(new FileInputStream(tmpfile), "file.tmp")).build();
        final HttpStrictMultipart multipart = new HttpStrictMultipart(null, "foo",
                Arrays.asList(p1, p2));

        final ByteArrayOutputStream out = new ByteArrayOutputStream();
        multipart.writeTo(out);
        out.close();

        final String expected =
            "--foo\r\n" +
            "Content-Type: application/octet-stream\r\n" +
            "\r\n" +
            "some random whatever\r\n" +
            "--foo\r\n" +
            "Content-Type: application/octet-stream\r\n" +
            "\r\n" +
            "some random whatever\r\n" +
            "--foo--\r\n";
        final String s = out.toString("US-ASCII");
        Assertions.assertEquals(expected, s);
        Assertions.assertEquals(-1, multipart.getTotalLength());
    }

    @Test
    public void testMultipartPartStrict() throws Exception {
        tmpfile = File.createTempFile("tmp", ".bin");
        try (Writer writer = new FileWriter(tmpfile)) {
            writer.append("some random whatever");
        }

        final MultipartPart p1 = MultipartPartBuilder.create(
                new FileBody(tmpfile)).build();
        final MultipartPart p2 = MultipartPartBuilder.create(
                new FileBody(tmpfile, ContentType.create("text/plain", "ANSI_X3.4-1968"), "test-file")).build();
        @SuppressWarnings("resource")
        final MultipartPart p3 = MultipartPartBuilder.create(
                new InputStreamBody(new FileInputStream(tmpfile), "file.tmp")).build();
        final HttpStrictMultipart multipart = new HttpStrictMultipart(null, "foo",
                Arrays.asList(p1, p2, p3));

        final ByteArrayOutputStream out = new ByteArrayOutputStream();
        multipart.writeTo(out);
        out.close();

        final String expected =
            "--foo\r\n" +
            "Content-Type: application/octet-stream\r\n" +
            "\r\n" +
            "some random whatever\r\n" +
            "--foo\r\n" +
            "Content-Type: text/plain; charset=US-ASCII\r\n" +
            "\r\n" +
            "some random whatever\r\n" +
            "--foo\r\n" +
            "Content-Type: application/octet-stream\r\n" +
            "\r\n" +
            "some random whatever\r\n" +
            "--foo--\r\n";
        final String s = out.toString("US-ASCII");
        Assertions.assertEquals(expected, s);
        Assertions.assertEquals(-1, multipart.getTotalLength());
    }

    @Test
    public void testMultipartPartRFC6532() throws Exception {
        tmpfile = File.createTempFile("tmp", ".bin");
        try (Writer writer = new FileWriter(tmpfile)) {
            writer.append("some random whatever");
        }

        final MultipartPart p1 = MultipartPartBuilder.create(
                new FileBody(tmpfile)).build();
        final MultipartPart p2 = MultipartPartBuilder.create(
                new FileBody(tmpfile, ContentType.create("text/plain", "ANSI_X3.4-1968"), "test-file")).build();
        @SuppressWarnings("resource")
        final MultipartPart p3 = MultipartPartBuilder.create(
                new InputStreamBody(new FileInputStream(tmpfile), "file.tmp")).build();
        final HttpRFC6532Multipart multipart = new HttpRFC6532Multipart(null, "foo",
                Arrays.asList(p1, p2, p3));

        final ByteArrayOutputStream out = new ByteArrayOutputStream();
        multipart.writeTo(out);
        out.close();

        final String expected =
            "--foo\r\n" +
            "Content-Type: application/octet-stream\r\n" +
            "\r\n" +
            "some random whatever\r\n" +
            "--foo\r\n" +
            "Content-Type: text/plain; charset=US-ASCII\r\n" +
            "\r\n" +
            "some random whatever\r\n" +
            "--foo\r\n" +
            "Content-Type: application/octet-stream\r\n" +
            "\r\n" +
            "some random whatever\r\n" +
            "--foo--\r\n";
        final String s = out.toString("UTF-8");
        Assertions.assertEquals(expected, s);
        Assertions.assertEquals(-1, multipart.getTotalLength());
    }

    private static final int SWISS_GERMAN_HELLO [] = {
        0x47, 0x72, 0xFC, 0x65, 0x7A, 0x69, 0x5F, 0x7A, 0xE4, 0x6D, 0xE4
    };

    private static final int RUSSIAN_HELLO [] = {
        0x412, 0x441, 0x435, 0x43C, 0x5F, 0x43F, 0x440, 0x438,
        0x432, 0x435, 0x442
    };

    private static String constructString(final int [] unicodeChars) {
        final StringBuilder buffer = new StringBuilder();
        if (unicodeChars != null) {
            for (final int unicodeChar : unicodeChars) {
                buffer.append((char)unicodeChar);
            }
        }
        return buffer.toString();
    }

    @Test
    public void testMultipartPartBrowserCompatibleNonASCIIHeaders() throws Exception {
        final String s1 = constructString(SWISS_GERMAN_HELLO);
        final String s2 = constructString(RUSSIAN_HELLO);

        tmpfile = File.createTempFile("tmp", ".bin");
        try (Writer writer = new FileWriter(tmpfile)) {
            writer.append("some random whatever");
        }

        @SuppressWarnings("resource")
        final MultipartPart p1 = MultipartPartBuilder.create(
                new InputStreamBody(new FileInputStream(tmpfile), s1 + ".tmp")).build();
        @SuppressWarnings("resource")
        final MultipartPart p2 = MultipartPartBuilder.create(
                new InputStreamBody(new FileInputStream(tmpfile), s2 + ".tmp")).build();
        final LegacyMultipart multipart = new LegacyMultipart(
                StandardCharsets.UTF_8, "foo",
                Arrays.asList(p1, p2));

        final ByteArrayOutputStream out = new ByteArrayOutputStream();
        multipart.writeTo(out);
        out.close();

        final String expected =
            "--foo\r\n" +
            "Content-Type: application/octet-stream\r\n" +
            "\r\n" +
            "some random whatever\r\n" +
            "--foo\r\n" +
            "Content-Type: application/octet-stream\r\n" +
            "\r\n" +
            "some random whatever\r\n" +
            "--foo--\r\n";
        final String s = out.toString("UTF-8");
        Assertions.assertEquals(expected, s);
        Assertions.assertEquals(-1, multipart.getTotalLength());
    }

    @Test
    public void testMultipartPartStringPartsMultiCharsets() throws Exception {
        final String s1 = constructString(SWISS_GERMAN_HELLO);
        final String s2 = constructString(RUSSIAN_HELLO);

        final MultipartPart p1 = MultipartPartBuilder.create(
                new StringBody(s1, ContentType.create("text/plain", StandardCharsets.ISO_8859_1))).build();
        final MultipartPart p2 = MultipartPartBuilder.create(
                new StringBody(s2, ContentType.create("text/plain", Charset.forName("KOI8-R")))).build();
        final HttpStrictMultipart multipart = new HttpStrictMultipart(null, "foo",
                Arrays.asList(p1, p2));

        final ByteArrayOutputStream out1 = new ByteArrayOutputStream();
        multipart.writeTo(out1);
        out1.close();

        final ByteArrayOutputStream out2 = new ByteArrayOutputStream();

        out2.write((
            "--foo\r\n" +
            "Content-Type: text/plain; charset=ISO-8859-1\r\n" +
            "\r\n").getBytes(StandardCharsets.US_ASCII));
        out2.write(s1.getBytes(StandardCharsets.ISO_8859_1));
        out2.write(("\r\n" +
            "--foo\r\n" +
            "Content-Type: text/plain; charset=KOI8-R\r\n" +
            "\r\n").getBytes(StandardCharsets.US_ASCII));
        out2.write(s2.getBytes(Charset.forName("KOI8-R")));
        out2.write(("\r\n" +
            "--foo--\r\n").getBytes(StandardCharsets.US_ASCII));
        out2.close();

        final byte[] actual = out1.toByteArray();
        final byte[] expected = out2.toByteArray();

        Assertions.assertEquals(expected.length, actual.length);
        for (int i = 0; i < actual.length; i++) {
            Assertions.assertEquals(expected[i], actual[i]);
        }
        Assertions.assertEquals(expected.length, multipart.getTotalLength());
    }

}
