// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.jrt;

public class TlsDetectionTest {

    static private String message(byte[] data, boolean actual) {
        String msg = "[";
        String delimiter = "";
        for (byte b: data) {
            msg += delimiter + (b & 0xff);
            delimiter = ", ";
        }
        if (actual) {
            msg += "] wrongfully detected as tls";
        } else {
            msg += "] wrongfully rejected as not tls";
        }
        return msg;
    }

    static private void checkTls(boolean expect, int ... values) {
        byte[] data = new byte[values.length];
        for (int i = 0; i < data.length; i++) {
            data[i] = (byte) values[i];
        }
        boolean actual = MaybeTlsCryptoSocket.looksLikeTlsToMe(data);
        if(actual != expect) {
            throw new AssertionError(message(data, actual));
        }
    }

    @org.junit.Test public void testValidHandshake() {
        checkTls(true, 22, 3, 1, 10, 255, 1, 0, 10, 251);
        checkTls(true, 22, 3, 3, 10, 255, 1, 0, 10, 251);
    }

    @org.junit.Test public void testDataOfWrongSize() {
        checkTls(false, 22, 3, 1, 10, 255, 1, 0, 10);
        checkTls(false, 22, 3, 1, 10, 255, 1, 0, 10, 251, 0);
    }

    @org.junit.Test public void testDataNotTaggedAsHandshake() {
        checkTls(false, 23, 3, 1, 10, 255, 1, 0, 10, 251);
    }

    @org.junit.Test public void testDataWithBadMajorVersion() {
        checkTls(false, 22, 0, 1, 10, 255, 1, 0, 10, 251);
        checkTls(false, 22, 1, 1, 10, 255, 1, 0, 10, 251);
        checkTls(false, 22, 2, 1, 10, 255, 1, 0, 10, 251);
        checkTls(false, 22, 4, 1, 10, 255, 1, 0, 10, 251);
        checkTls(false, 22, 5, 1, 10, 255, 1, 0, 10, 251);
    }

    @org.junit.Test public void testDataWithBadMinorVersion() {
        checkTls(false, 22, 3, 0, 10, 255, 1, 0, 10, 251);
        checkTls(false, 22, 3, 2, 10, 255, 1, 0, 10, 251);
        checkTls(false, 22, 3, 4, 10, 255, 1, 0, 10, 251);
        checkTls(false, 22, 3, 5, 10, 255, 1, 0, 10, 251);
    }

    @org.junit.Test public void testDataNotTaggedAsClientHello() {
        checkTls(false, 22, 3, 1, 10, 255, 0, 0, 10, 251);
        checkTls(false, 22, 3, 1, 10, 255, 2, 0, 10, 251);
    }

    @org.junit.Test public void testFrameSizeLimits() {
        checkTls(false, 22, 3, 1, 255, 255, 1,   0, 255, 251); // max
        checkTls(false, 22, 3, 1,  72,   1, 1,   0,  71, 253); // 18k + 1
        checkTls(true,  22, 3, 1,  72,   0, 1,   0,  71, 252); // 18k
        checkTls(true,  22, 3, 1,   0,   4, 1,   0,   0,   0); // 4
        checkTls(false, 22, 3, 1,   0,   3, 1,   0,   0,   0); // 3 - capped
        checkTls(false, 22, 3, 1,   0,   3, 1, 255, 255, 255); // 3 - wrapped
    }

    @org.junit.Test public void testFrameAndClientHelloSizeRelationship() {
        checkTls(true,  22, 3, 1, 10, 255, 1, 0, 10, 251);
        checkTls(false, 22, 3, 1, 10, 255, 1, 1, 10, 251);
        checkTls(false, 22, 3, 1, 10, 255, 1, 2, 10, 251);

        checkTls(false, 22, 3, 1, 10, 5, 1, 0, 10, 0);
        checkTls(true,  22, 3, 1, 10, 5, 1, 0, 10, 1);
        checkTls(false, 22, 3, 1, 10, 5, 1, 0, 10, 2);

        checkTls(false, 22, 3, 1, 10, 5, 1, 0,  9, 1);
        checkTls(true,  22, 3, 1, 10, 5, 1, 0, 10, 1);
        checkTls(false, 22, 3, 1, 10, 5, 1, 0, 11, 1);

        checkTls(true, 22, 3, 1, 10, 5, 1, 0, 10,   1);
        checkTls(true, 22, 3, 1, 10, 4, 1, 0, 10,   0);
        checkTls(true, 22, 3, 1, 10, 3, 1, 0,  9, 255);
        checkTls(true, 22, 3, 1, 10, 2, 1, 0,  9, 254);
        checkTls(true, 22, 3, 1, 10, 1, 1, 0,  9, 253);
        checkTls(true, 22, 3, 1, 10, 0, 1, 0,  9, 252);
    }
}

@@ -136,16 +136,62 @@
 o.jrt;%0A%0A
+import static org.junit.Assert.assertEquals;%0A%0A
 public c
@@ -925,67 +925,20 @@
     
-if(actual != expect) %7B%0A            throw new AssertionError
+assertEquals
 (mes
@@ -959,20 +959,26 @@
 ual)
-);%0A        %7D
+, expect, actual);
 %0A   

use junit assert