# 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 'google/protobuf/well_known_types'
require_relative '../pb/src/proto/grpc/testing/messages_pb'

describe GRPC::BadStatus do
  describe :attributes do
    it 'has attributes' do
      code = 1
      details = 'details'
      metadata = { 'key' => 'val' }

      exception = GRPC::BadStatus.new(code, details, metadata)

      expect(exception.code).to eq code
      expect(exception.details).to eq details
      expect(exception.metadata).to eq metadata
    end
  end

  describe :new_status_exception do
    let(:codes_and_classes) do
      [
        [GRPC::Core::StatusCodes::OK, GRPC::Ok],
        [GRPC::Core::StatusCodes::CANCELLED, GRPC::Cancelled],
        [GRPC::Core::StatusCodes::UNKNOWN, GRPC::Unknown],
        [GRPC::Core::StatusCodes::INVALID_ARGUMENT, GRPC::InvalidArgument],
        [GRPC::Core::StatusCodes::DEADLINE_EXCEEDED, GRPC::DeadlineExceeded],
        [GRPC::Core::StatusCodes::NOT_FOUND, GRPC::NotFound],
        [GRPC::Core::StatusCodes::ALREADY_EXISTS, GRPC::AlreadyExists],
        [GRPC::Core::StatusCodes::PERMISSION_DENIED, GRPC::PermissionDenied],
        [GRPC::Core::StatusCodes::UNAUTHENTICATED, GRPC::Unauthenticated],
        [GRPC::Core::StatusCodes::RESOURCE_EXHAUSTED, GRPC::ResourceExhausted],
        [GRPC::Core::StatusCodes::FAILED_PRECONDITION, GRPC::FailedPrecondition],
        [GRPC::Core::StatusCodes::ABORTED, GRPC::Aborted],
        [GRPC::Core::StatusCodes::OUT_OF_RANGE, GRPC::OutOfRange],
        [GRPC::Core::StatusCodes::UNIMPLEMENTED, GRPC::Unimplemented],
        [GRPC::Core::StatusCodes::INTERNAL, GRPC::Internal],
        [GRPC::Core::StatusCodes::UNAVAILABLE, GRPC::Unavailable],
        [GRPC::Core::StatusCodes::DATA_LOSS, GRPC::DataLoss],
        [99, GRPC::BadStatus] # Unknown codes default to BadStatus
      ]
    end

    it 'maps codes to the correct error class' do
      codes_and_classes.each do |code, grpc_error_class|
        exception = GRPC::BadStatus.new_status_exception(code)

        expect(exception).to be_a grpc_error_class
      end
    end
  end

  describe :to_status do
    it 'gets status' do
      code = 1
      details = 'details'
      metadata = { 'key' => 'val' }

      exception = GRPC::BadStatus.new(code, details, metadata)
      status = Struct::Status.new(code, details, metadata)

      expect(exception.to_status).to eq status
    end
  end

  describe :to_rpc_status do
    let(:simple_request_any) do
      Google::Protobuf::Any.new.tap do |any|
        any.pack(
          Grpc::Testing::SimpleRequest.new(
            payload: Grpc::Testing::Payload.new(body: 'request')
          )
        )
      end
    end
    let(:simple_response_any) do
      Google::Protobuf::Any.new.tap do |any|
        any.pack(
          Grpc::Testing::SimpleResponse.new(
            payload: Grpc::Testing::Payload.new(body: 'response')
          )
        )
      end
    end
    let(:payload_any) do
      Google::Protobuf::Any.new.tap do |any|
        any.pack(Grpc::Testing::Payload.new(body: 'payload'))
      end
    end

    it 'decodes proto values' do
      rpc_status = Google::Rpc::Status.new(
        code: 1,
        message: 'matching message',
        details: [simple_request_any, simple_response_any, payload_any]
      )
      rpc_status_proto = Google::Rpc::Status.encode(rpc_status)

      code = 1
      details = 'details'
      metadata = { 'grpc-status-details-bin' => rpc_status_proto }

      exception = GRPC::BadStatus.new(code, details, metadata)

      expect(exception.to_rpc_status).to eq rpc_status
    end

    it 'does not raise when decoding a bad proto' do
      code = 1
      details = 'details'
      metadata = { 'grpc-status-details-bin' => 'notavalidprotostream' }

      exception = GRPC::BadStatus.new(code, details, metadata)

      expect(exception.to_rpc_status).to be nil

      error_msg = 'parse error: to_rpc_status failed'
      error_desc = '<Google::Protobuf::ParseError> ' \
        'Error occurred during parsing: Invalid wire type'

      # Check that the parse error was logged correctly
      log_contents = @log_output.read
      expect(log_contents).to include "WARN  GRPC : #{error_msg}"
      expect(log_contents).to include "WARN  GRPC : #{error_desc}"
    end
  end
end
