# Copyright 2015 gRPC authors.
#
# Licensed 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.

require 'spec_helper'
require 'English'

def load_test_certs
  test_root = File.join(File.dirname(__FILE__), 'testdata')
  files = ['ca.pem', 'server1.key', 'server1.pem']
  files.map { |f| File.open(File.join(test_root, f)).read }
end

describe GRPC::Core::Channel do
  let(:fake_host) { 'localhost:0' }

  def create_test_cert
    GRPC::Core::ChannelCredentials.new(load_test_certs[0])
  end

  def fork_with_propagated_error_message
    pipe_read, pipe_write = IO.pipe
    pid = fork do
      pipe_read.close
      begin
        yield
      rescue => exc
        pipe_write.syswrite(exc.message)
      end
      pipe_write.close
    end
    pipe_write.close

    exc_message = pipe_read.read
    Process.wait(pid)

    unless $CHILD_STATUS.success?
      raise "forked process failed with #{$CHILD_STATUS}"
    end
    raise exc_message unless exc_message.empty?
  end

  shared_examples '#new' do
    it 'take a host name without channel args' do
      blk = proc do
        GRPC::Core::Channel.new('dummy_host', nil, :this_channel_is_insecure)
      end
      expect(&blk).not_to raise_error
    end

    it 'does not take a hash with bad keys as channel args' do
      blk = construct_with_args(Object.new => 1)
      expect(&blk).to raise_error TypeError
      blk = construct_with_args(1 => 1)
      expect(&blk).to raise_error TypeError
    end

    it 'does not take a hash with bad values as channel args' do
      blk = construct_with_args(symbol: Object.new)
      expect(&blk).to raise_error TypeError
      blk = construct_with_args('1' => {})
      expect(&blk).to raise_error TypeError
    end

    it 'can take a hash with a symbol key as channel args' do
      blk = construct_with_args(a_symbol: 1)
      expect(&blk).to_not raise_error
    end

    it 'can take a hash with a string key as channel args' do
      blk = construct_with_args('a_symbol' => 1)
      expect(&blk).to_not raise_error
    end

    it 'can take a hash with a string value as channel args' do
      blk = construct_with_args(a_symbol: '1')
      expect(&blk).to_not raise_error
    end

    it 'can take a hash with a symbol value as channel args' do
      blk = construct_with_args(a_symbol: :another_symbol)
      expect(&blk).to_not raise_error
    end

    it 'can take a hash with a numeric value as channel args' do
      blk = construct_with_args(a_symbol: 1)
      expect(&blk).to_not raise_error
    end

    it 'can take a hash with many args as channel args' do
      args = Hash[127.times.collect { |x| [x.to_s, x] }]
      blk = construct_with_args(args)
      expect(&blk).to_not raise_error
    end

    it 'raises if grpc was initialized in another process' do
      blk = construct_with_args({})
      expect(&blk).not_to raise_error
      expect do
        fork_with_propagated_error_message(&blk)
      end.to raise_error(RuntimeError, 'grpc cannot be used before and after forking')
    end
  end

  describe '#new for secure channels' do
    def construct_with_args(a)
      proc { GRPC::Core::Channel.new('dummy_host', a, create_test_cert) }
    end

    it_behaves_like '#new'
  end

  describe '#new for insecure channels' do
    it_behaves_like '#new'

    def construct_with_args(a)
      proc do
        GRPC::Core::Channel.new('dummy_host', a, :this_channel_is_insecure)
      end
    end
  end

  describe '#create_call' do
    it 'creates a call OK' do
      ch = GRPC::Core::Channel.new(fake_host, nil, :this_channel_is_insecure)

      deadline = Time.now + 5

      blk = proc do
        ch.create_call(nil, nil, 'dummy_method', nil, deadline)
      end
      expect(&blk).to_not raise_error
    end

    it 'raises an error if called on a closed channel' do
      ch = GRPC::Core::Channel.new(fake_host, nil, :this_channel_is_insecure)
      ch.close

      deadline = Time.now + 5
      blk = proc do
        ch.create_call(nil, nil, 'dummy_method', nil, deadline)
      end
      expect(&blk).to raise_error(RuntimeError)
    end

    it 'raises if grpc was initialized in another process' do
      ch = GRPC::Core::Channel.new(fake_host, nil, :this_channel_is_insecure)

      deadline = Time.now + 5

      blk = proc do
        fork_with_propagated_error_message do
          ch.create_call(nil, nil, 'dummy_method', nil, deadline)
        end
      end
      expect(&blk).to raise_error(RuntimeError, 'grpc cannot be used before and after forking')
    end
  end

  describe '#destroy' do
    it 'destroys a channel ok' do
      ch = GRPC::Core::Channel.new(fake_host, nil, :this_channel_is_insecure)
      blk = proc { ch.destroy }
      expect(&blk).to_not raise_error
    end

    it 'can be called more than once without error' do
      ch = GRPC::Core::Channel.new(fake_host, nil, :this_channel_is_insecure)
      blk = proc { ch.destroy }
      blk.call
      expect(&blk).to_not raise_error
    end
  end

  describe '#connectivity_state' do
    it 'returns an enum' do
      ch = GRPC::Core::Channel.new(fake_host, nil, :this_channel_is_insecure)
      valid_states = [
        GRPC::Core::ConnectivityStates::IDLE,
        GRPC::Core::ConnectivityStates::CONNECTING,
        GRPC::Core::ConnectivityStates::READY,
        GRPC::Core::ConnectivityStates::TRANSIENT_FAILURE,
        GRPC::Core::ConnectivityStates::FATAL_FAILURE
      ]

      expect(valid_states).to include(ch.connectivity_state)
    end

    it 'returns an enum when trying to connect' do
      ch = GRPC::Core::Channel.new(fake_host, nil, :this_channel_is_insecure)
      ch.connectivity_state(true)
      valid_states = [
        GRPC::Core::ConnectivityStates::IDLE,
        GRPC::Core::ConnectivityStates::CONNECTING,
        GRPC::Core::ConnectivityStates::READY,
        GRPC::Core::ConnectivityStates::TRANSIENT_FAILURE,
        GRPC::Core::ConnectivityStates::FATAL_FAILURE
      ]

      expect(valid_states).to include(ch.connectivity_state)
    end
  end

  describe '::SSL_TARGET' do
    it 'is a symbol' do
      expect(GRPC::Core::Channel::SSL_TARGET).to be_a(Symbol)
    end
  end

  describe '#close' do
    it 'closes a channel ok' do
      ch = GRPC::Core::Channel.new(fake_host, nil, :this_channel_is_insecure)
      blk = proc { ch.close }
      expect(&blk).to_not raise_error
    end

    it 'can be called more than once without error' do
      ch = GRPC::Core::Channel.new(fake_host, nil, :this_channel_is_insecure)
      blk = proc { ch.close }
      blk.call
      expect(&blk).to_not raise_error
    end
  end
end
