<?php
/*
 *
 * Copyright 2015, Google Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

class ChannelTest extends PHPUnit_Framework_TestCase
{
    public function setUp()
    {
    }

    public function tearDown()
    {
        unset($this->channel);
    }

    public function testInsecureCredentials()
    {
        $this->channel = new Grpc\Channel(
            'localhost:0',
            [
                'credentials' => Grpc\ChannelCredentials::createInsecure(),
            ]
        );
        $this->assertSame('Grpc\Channel', get_class($this->channel));
    }

    public function testGetConnectivityState()
    {
        $this->channel = new Grpc\Channel('localhost:0',
             ['credentials' => Grpc\ChannelCredentials::createInsecure()]);
        $state = $this->channel->getConnectivityState();
        $this->assertEquals(0, $state);
    }

    public function testGetConnectivityStateWithInt()
    {
        $this->channel = new Grpc\Channel('localhost:0',
             ['credentials' => Grpc\ChannelCredentials::createInsecure()]);
        $state = $this->channel->getConnectivityState(123);
        $this->assertEquals(0, $state);
    }

    public function testGetConnectivityStateWithString()
    {
        $this->channel = new Grpc\Channel('localhost:0',
             ['credentials' => Grpc\ChannelCredentials::createInsecure()]);
        $state = $this->channel->getConnectivityState('hello');
        $this->assertEquals(0, $state);
    }

    public function testGetConnectivityStateWithBool()
    {
        $this->channel = new Grpc\Channel('localhost:0',
             ['credentials' => Grpc\ChannelCredentials::createInsecure()]);
        $state = $this->channel->getConnectivityState(true);
        $this->assertEquals(0, $state);
    }

    public function testGetTarget()
    {
        $this->channel = new Grpc\Channel('localhost:8888',
             ['credentials' => Grpc\ChannelCredentials::createInsecure()]);
        $target = $this->channel->getTarget();
        $this->assertTrue(is_string($target));
    }

    public function testWatchConnectivityState()
    {
        $this->channel = new Grpc\Channel('localhost:0',
             ['credentials' => Grpc\ChannelCredentials::createInsecure()]);
        $time = new Grpc\Timeval(1000);
        $state = $this->channel->watchConnectivityState(1, $time);
        $this->assertTrue($state);
        unset($time);
    }

    public function testClose()
    {
        $this->channel = new Grpc\Channel('localhost:0',
             ['credentials' => Grpc\ChannelCredentials::createInsecure()]);
        $this->assertNotNull($this->channel);
        $this->channel->close();
    }

    /**
     * @expectedException InvalidArgumentException
     */
    public function testInvalidConstructorWithNull()
    {
        $this->channel = new Grpc\Channel();
        $this->assertNull($this->channel);
    }

    /**
     * @expectedException InvalidArgumentException
     */
    public function testInvalidConstructorWith()
    {
        $this->channel = new Grpc\Channel('localhost', 'invalid');
        $this->assertNull($this->channel);
    }

    /**
     * @expectedException InvalidArgumentException
     */
    public function testInvalidCredentials()
    {
        $this->channel = new Grpc\Channel(
            'localhost:0',
            [
                'credentials' => new Grpc\Timeval(100),
            ]
        );
    }

    /**
     * @expectedException InvalidArgumentException
     */
    public function testInvalidOptionsArray()
    {
        $this->channel = new Grpc\Channel(
            'localhost:0',
            [
                'abc' => [],
            ]
        );
    }

    /**
     * @expectedException InvalidArgumentException
     */
    public function testInvalidGetConnectivityStateWithArray()
    {
        $this->channel = new Grpc\Channel('localhost:0',
            ['credentials' => Grpc\ChannelCredentials::createInsecure()]);
        $this->channel->getConnectivityState([]);
    }

    /**
     * @expectedException InvalidArgumentException
     */
    public function testInvalidWatchConnectivityState()
    {
        $this->channel = new Grpc\Channel('localhost:0',
            ['credentials' => Grpc\ChannelCredentials::createInsecure()]);
        $this->channel->watchConnectivityState([]);
    }

    /**
     * @expectedException InvalidArgumentException
     */
    public function testInvalidWatchConnectivityState2()
    {
        $this->channel = new Grpc\Channel('localhost:0',
            ['credentials' => Grpc\ChannelCredentials::createInsecure()]);
        $this->channel->watchConnectivityState(1, 'hi');
    }
}
