# 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 'grpc/generic/rpc_desc'
require 'grpc/generic/service'

# A test message that encodes/decodes using marshal/marshal.
class GoodMsg
  def self.marshal(_o)
    ''
  end

  def self.unmarshal(_o)
    GoodMsg.new
  end
end

# A test message that encodes/decodes using encode/decode.
class EncodeDecodeMsg
  def self.encode(_o)
    ''
  end

  def self.decode(_o)
    GoodMsg.new
  end
end

GenericService = GRPC::GenericService
Dsl = GenericService::Dsl

describe Dsl do
  it 'can be included in new classes' do
    blk = proc { Class.new { include Dsl } }
    expect(&blk).to_not raise_error
  end
end

describe GenericService do
  context '#underscore' do
    it 'should convert CamelCase to underscore separated' do
      expect(GenericService.underscore('AnRPC')).to eq('an_rpc')
      expect(GenericService.underscore('AMethod')).to eq('a_method')
      expect(GenericService.underscore('PrintHTML')).to eq('print_html')
      expect(GenericService.underscore('SeeHTMLBooks')).to eq('see_html_books')
    end
  end

  describe 'including it' do
    it 'adds a class method, rpc' do
      c = Class.new do
        include GenericService
      end
      expect(c.methods).to include(:rpc)
    end

    it 'adds rpc descs using the added class method, #rpc' do
      c = Class.new do
        include GenericService
        rpc :AnRpc, GoodMsg, GoodMsg
      end

      expect(c.rpc_descs).to include(:AnRpc)
      expect(c.rpc_descs[:AnRpc]).to be_a(GRPC::RpcDesc)
    end

    it 'give subclasses access to #rpc_descs' do
      base = Class.new do
        include GenericService
        rpc :AnRpc, GoodMsg, GoodMsg
      end
      c = Class.new(base) do
      end
      expect(c.rpc_descs).to include(:AnRpc)
      expect(c.rpc_descs[:AnRpc]).to be_a(GRPC::RpcDesc)
    end

    it 'adds a default service name' do
      c = Class.new do
        include GenericService
      end
      expect(c.service_name).to eq('GenericService')
    end

    it 'adds a default service name to subclasses' do
      base = Class.new do
        include GenericService
      end
      c = Class.new(base) do
      end
      expect(c.service_name).to eq('GenericService')
    end

    it 'adds the specified service name' do
      c = Class.new do
        include GenericService
        self.service_name = 'test.service.TestService'
      end
      expect(c.service_name).to eq('test.service.TestService')
    end

    it 'adds the specified service name to subclasses' do
      base = Class.new do
        include GenericService
        self.service_name = 'test.service.TestService'
      end
      c = Class.new(base) do
      end
      expect(c.service_name).to eq('test.service.TestService')
    end
  end

  describe '#include' do
    it 'raises if #rpc is missing an arg' do
      blk = proc do
        Class.new do
          include GenericService
          rpc :AnRpc, GoodMsg
        end
      end
      expect(&blk).to raise_error ArgumentError

      blk = proc do
        Class.new do
          include GenericService
          rpc :AnRpc
        end
      end
      expect(&blk).to raise_error ArgumentError
    end

    describe 'when #rpc args are incorrect' do
      it 'raises if an arg does not have the marshal or unmarshal methods' do
        blk = proc do
          Class.new do
            include GenericService
            rpc :AnRpc, GoodMsg, Object
          end
        end
        expect(&blk).to raise_error ArgumentError
      end

      it 'raises if a type arg only has the marshal method' do
        # a bad message type with only a marshal method
        class OnlyMarshal
          def marshal(o)
            o
          end
        end

        blk = proc do
          Class.new do
            include GenericService
            rpc :AnRpc, OnlyMarshal, GoodMsg
          end
        end
        expect(&blk).to raise_error ArgumentError
      end

      it 'raises if a type arg only has the unmarshal method' do
        # a bad message type with only an unmarshal method
        class OnlyUnmarshal
          def self.ummarshal(o)
            o
          end
        end
        blk = proc do
          Class.new do
            include GenericService
            rpc :AnRpc, GoodMsg, OnlyUnmarshal
          end
        end
        expect(&blk).to raise_error ArgumentError
      end
    end

    it 'is ok for services that expect the default {un,}marshal methods' do
      blk = proc do
        Class.new do
          include GenericService
          rpc :AnRpc, GoodMsg, GoodMsg
        end
      end
      expect(&blk).not_to raise_error
    end

    it 'is ok for services that override the default {un,}marshal methods' do
      blk = proc do
        Class.new do
          include GenericService
          self.marshal_class_method = :encode
          self.unmarshal_class_method = :decode
          rpc :AnRpc, EncodeDecodeMsg, EncodeDecodeMsg
        end
      end
      expect(&blk).not_to raise_error
    end
  end

  describe '#rpc_stub_class' do
    it 'generates a client class that defines any of the rpc methods' do
      s = Class.new do
        include GenericService
        rpc :AnRpc, GoodMsg, GoodMsg
        rpc :AServerStreamer, GoodMsg, stream(GoodMsg)
        rpc :AClientStreamer, stream(GoodMsg), GoodMsg
        rpc :ABidiStreamer, stream(GoodMsg), stream(GoodMsg)
      end
      client_class = s.rpc_stub_class
      expect(client_class.instance_methods).to include(:an_rpc)
      expect(client_class.instance_methods).to include(:a_server_streamer)
      expect(client_class.instance_methods).to include(:a_client_streamer)
      expect(client_class.instance_methods).to include(:a_bidi_streamer)
    end

    describe 'the generated instances' do
      it 'can be instanciated with just a hostname and credentials' do
        s = Class.new do
          include GenericService
          rpc :AnRpc, GoodMsg, GoodMsg
          rpc :AServerStreamer, GoodMsg, stream(GoodMsg)
          rpc :AClientStreamer, stream(GoodMsg), GoodMsg
          rpc :ABidiStreamer, stream(GoodMsg), stream(GoodMsg)
        end
        client_class = s.rpc_stub_class
        blk = proc do
          client_class.new('fakehostname', :this_channel_is_insecure)
        end
        expect(&blk).not_to raise_error
      end

      it 'has the methods defined in the service' do
        s = Class.new do
          include GenericService
          rpc :AnRpc, GoodMsg, GoodMsg
          rpc :AServerStreamer, GoodMsg, stream(GoodMsg)
          rpc :AClientStreamer, stream(GoodMsg), GoodMsg
          rpc :ABidiStreamer, stream(GoodMsg), stream(GoodMsg)
        end
        client_class = s.rpc_stub_class
        o = client_class.new('fakehostname', :this_channel_is_insecure)
        expect(o.methods).to include(:an_rpc)
        expect(o.methods).to include(:a_bidi_streamer)
        expect(o.methods).to include(:a_client_streamer)
        expect(o.methods).to include(:a_bidi_streamer)
      end
    end
  end
end
