require 'rails_helper'

RSpec.describe ZoomGateway do
  let(:roles_list_response) { {"roles" => [{"name" => 'pro-directme-host', "id" => "host_role_id"}, {"name" => 'basic-directme-host', "id" => "host_role_id"}]} }
  let(:host_user_hash) { {"email" => "user1@directme", "id" => "host_user_id"} }
  let(:roles_members_response) { {"members" => [host_user_hash]} }
  let(:user_create_response) { {"id" => "new_host_id"} }
  let(:roles_assign_response) { {"ids" => ["new_host_id"]} }
  let(:meeting_hash) { {"id" => "meeting_id", "start_url" => "https://start_url", "join_url" => "https://join_url"} }
  let(:gateway) { ZoomGateway.new }

  describe "pseudo-constants" do
    context '.USER_TYPE_NAME' do
      it 'defaults to "basic"' do
        expect(ZoomGateway.USER_TYPE_NAME).to eq('basic')
      end

      it 'depends ENV["ZOOM_USER_TYPE"]' do
        stub_env_variable('ZOOM_USER_TYPE', 'pro')
        expect(ZoomGateway.USER_TYPE_NAME).to eq('pro')
      end

      it 'only accepts "pro" as an alternative' do
        stub_env_variable('ZOOM_USER_TYPE', 'wrong')
        expect(ZoomGateway.USER_TYPE_NAME).to eq('basic')
      end
    end

    context '.USER_TYPE' do
      it 'defaults to 1 (basic)' do
        expect(ZoomGateway.USER_TYPE).to eq(1)
      end

      it 'depends on ENV["ZOOM_USER_TYPE"]' do
        stub_env_variable('ZOOM_USER_TYPE', 'pro')
        expect(ZoomGateway.USER_TYPE).to eq(2)
      end

      it 'only accepts "pro" as an alternative to "basic"' do
        stub_env_variable('ZOOM_USER_TYPE', 'wrong')
        expect(ZoomGateway.USER_TYPE).to eq(1)
      end
    end

    context '.USER_LIMIT' do
      it 'defaults to 3' do
        expect(ZoomGateway.PRO_USERS_LIMIT).to eq(3)
      end

      it 'depends on ENV["ZOOM_PRO_USERS_LIMIT"]' do
        stub_env_variable('ZOOM_PRO_USERS_LIMIT', 10)
        expect(ZoomGateway.PRO_USERS_LIMIT).to eq(10)
      end
    end

    context '.HOST_ROLE' do
      it 'has a default' do
        expect(ZoomGateway.HOST_ROLE).to eq('basic-directme-host')
      end

      it 'depends on user type' do
        stub_env_variable('ZOOM_USER_TYPE', 'pro')
        expect(ZoomGateway.HOST_ROLE).to eq('pro-directme-host')
      end
    end

    context '.ACCOUNT_NUMBER' do
      it 'depends on ENV["ZOOM_ACCOUNT_NUMBER"]' do
        stub_env_variable('ZOOM_ACCOUNT_NUMBER', 'xxx-yyy-zzz')
        expect(ZoomGateway.ACCOUNT_NUMBER).to eq('xxx-yyy-zzz')
      end
    end
  end

  describe 'static methods' do
    context '.enable_recordings?' do
      it 'is truthy when ZOOM_ENABLE_RECORDINGS is set to true' do
        stub_env_variable('ZOOM_ENABLE_RECORDINGS', 'true')
        expect(ZoomGateway.enable_recordings?).to be_truthy
      end

      it 'is falsey otherwise' do
        stub_env_variable('ZOOM_ENABLE_RECORDINGS', '1')
        expect(ZoomGateway.enable_recordings?).to be_falsey

        stub_env_variable('ZOOM_ENABLE_RECORDINGS', 'false')
        expect(ZoomGateway.enable_recordings?).to be_falsey
      end
    end

    context '.host_role_name' do
      it 'returns given name with -directme-host prefix' do
        expect(ZoomGateway.host_role_name('prefix')).to eq('prefix-directme-host')
      end
    end
  end

  describe ".find_meeting" do
    it "returns meeting hash" do
      allow_any_instance_of(Zoom.new.class).to receive(:meeting_get).and_return(meeting_hash)

      meeting = gateway.find_meeting("meeting_id")
      expect(meeting).to eq(meeting_hash)
    end
  end

  describe ".create_meeting" do
    before(:each) { allow_any_instance_of(Zoom.new.class).to receive(:meeting_create).and_return(meeting_hash) }

    it "returns a meeting id" do
      meeting_id = gateway.create_meeting(topic: "Test topic", user_id: "user_id")
      expect(meeting_id).to eq("meeting_id")
    end
  end

  describe ".create_host" do
    before do
      allow_any_instance_of(Zoom.new.class).to receive(:roles_list).and_return(roles_list_response)
    end

    it "returns new host id" do
      allow_any_instance_of(Zoom.new.class).to receive(:user_create).and_return(user_create_response)
      allow_any_instance_of(Zoom.new.class).to receive(:roles_assign).and_return(roles_assign_response)

      expect(gateway.create_host("host-email@address")).to eq("new_host_id")
    end

    context 'USER_TYPE=pro and PRO_USERS_LIMIT exceeded' do
      before :each do
        allow_any_instance_of(Zoom.new.class).to receive(:roles_members).and_return({'total_records' => 2})
      end

      it 'raises an exception' do
        stub_env_variables(ZOOM_USER_TYPE: 'pro', ZOOM_PRO_USERS_LIMIT: 2)

        expect { gateway.create_host('host-email@address') }.to raise_error(ZoomGateway::TooManyHosts)
      end
    end
  end

  describe '.delete_recording' do
    it 'calls api client to delete recording' do
      expect_any_instance_of(Zoom.new.class).to receive(:recording_delete)
      gateway.delete_recording('meeting-id', 'recording-id')
    end
  end

end
