/*
 * 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.commons.net.telnet;

import junit.framework.TestCase;
import java.io.InputStream;
import java.io.OutputStream;

/***
 * JUnit functional test for TelnetClient.
 * Connects to the weather forecast service
 * rainmaker.wunderground.com and asks for Los Angeles forecast.
 ***/
public class TelnetClientFunctionalTest extends TestCase
{
    protected TelnetClient tc1;

    /***
     * test setUp
     ***/
    @Override
    protected void setUp()
    {
        tc1 = new TelnetClient();
    }

    /*
     * Do the functional test:
     * - connect to the weather service
     * - press return on the first menu
     * - send LAX on the second menu
     * - send X to exit
     ***/
    public void testFunctionalTest() throws Exception
    {
        boolean testresult = false;
        tc1.connect("rainmaker.wunderground.com", 3000);

        try (final InputStream is = tc1.getInputStream(); 
            final OutputStream os = tc1.getOutputStream()) {

            boolean cont = waitForString(is, "Return to continue:", 30000);
            if (cont) {
                os.write("\n".getBytes());
                os.flush();
                cont = waitForString(is, "city code--", 30000);
            }
            if (cont) {
                os.write("LAX\n".getBytes());
                os.flush();
                cont = waitForString(is, "Los Angeles", 30000);
            }
            if (cont) {
                cont = waitForString(is, "X to exit:", 30000);
            }
            if (cont) {
                os.write("X\n".getBytes());
                os.flush();
                tc1.disconnect();
                testresult = true;
            }

            assertTrue(testresult);
        }
    }


    /*
     * Helper method. waits for a string with timeout
     */
    public boolean waitForString(final InputStream is, final String end, final long timeout) throws Exception
    {
        final byte buffer[] = new byte[32];
        final long starttime = System.currentTimeMillis();

        String readbytes = "";
        while((readbytes.indexOf(end) < 0) &&
              ((System.currentTimeMillis() - starttime) < timeout))
        {
            if(is.available() > 0)
            {
                final int ret_read = is.read(buffer);
                readbytes = readbytes + new String(buffer, 0, ret_read);
            }
            else
            {
                Thread.sleep(500);
            }
        }

        if(readbytes.indexOf(end) >= 0)
        {
            return (true);
        }
        return (false);
    }
}