/*
 *  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.coyote.http2;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

import org.junit.Assert;
import org.junit.Test;

import org.apache.catalina.util.ServerInfo;
import org.apache.catalina.valves.ErrorReportValve;
import org.apache.tomcat.util.res.StringManager;

public class TestHttp2InitialConnection extends Http2TestBase {

    private TestData testData;


    @Test
    public void testValidHostHeader() throws Exception {
        List<String> hostHeaders = new ArrayList<>(1);
        hostHeaders.add("localhost:8080");

        testData = new TestData(hostHeaders, 200);

        http2Connect();
    }


    @Test
    public void testMultipleHostHeaders() throws Exception {
        List<String> hostHeaders = new ArrayList<>(1);
        hostHeaders.add("localhost:8080");
        hostHeaders.add("localhost:8081");

        testData = new TestData(hostHeaders, 400);

        http2Connect();
    }


    @Test
    public void testNoHostHeader() throws Exception {
        List<String> hostHeaders = new ArrayList<>(1);

        testData = new TestData(hostHeaders, 400);
        http2Connect();
    }


    @Override
    protected void doHttpUpgrade(String connection, String upgrade, String settings,
            boolean validate) throws IOException {
        StringBuilder request = new StringBuilder();
        request.append("GET /simple HTTP/1.1\r\n");
        for (String hostHeader : testData.getHostHeaders()) {
            request.append("Host: ");
            request.append(hostHeader);
            request.append("\r\n");
        }
        // Connection
        request.append("Connection: ");
        request.append(connection);
        request.append("\r\n");
        // Upgrade
        request.append("Upgrade: ");
        request.append(upgrade);
        request.append("\r\n");
        // Settings
        request.append(settings);
        // Request terminator
        request.append("\r\n");

        byte[] upgradeRequest = request.toString().getBytes(StandardCharsets.ISO_8859_1);
        os.write(upgradeRequest);
        os.flush();

        if (validate) {
            Assert.assertTrue("Failed to read HTTP Upgrade response",
                    readHttpUpgradeResponse());
        }
    }


    @Override
    protected String getResponseBodyFrameTrace(int streamId, String body) {
        if (testData.getExpectedStatus() == 200) {
            return super.getResponseBodyFrameTrace(streamId, body);
        } else if (testData.getExpectedStatus() == 400) {
            /*
             * Need to be careful here. The test wants the exact content length
             * in bytes.
             * This will vary depending on where the test is run due to:
             * - The length of the version string that appears once in the error
             *   page
             * - The status header uses a UTF-8 EM dash. When running in an IDE
             *   the UTF-8 properties files will be used directly rather than
             *   after native2ascii conversion.
             *
             * Note: The status header appears twice in the error page.
             */
            int serverInfoLength = ServerInfo.getServerInfo().getBytes().length;
            StringManager sm = StringManager.getManager(ErrorReportValve.class);
            int statusHeaderLength = sm.getString(
                    "errorReportValve.statusHeader", "", "").getBytes().length;
            int len = 1073 + serverInfoLength + statusHeaderLength * 2;
            String contentLength = String.valueOf(len);
            return getResponseBodyFrameTrace(streamId, testData.getExpectedStatus(),
                    "text/html;charset=utf-8", "en", contentLength, contentLength);
        } else {
            Assert.fail();
            // To keep the IDE happy
            return null;
        }
    }


    private static class TestData {
        private final List<String> hostHeaders;
        private final int expectedStatus;

        public TestData(List<String> hostHeaders, int expectedStatus) {
            this.hostHeaders = hostHeaders;
            this.expectedStatus = expectedStatus;
        }

        public List<String> getHostHeaders() {
            return hostHeaders;
        }

        public int getExpectedStatus() {
            return expectedStatus;
        }
    }
}
