require 'rails_helper'

RSpec.describe Chronobreak::Tenure do
  include ServiceHelper

  describe 'preview_tenure_with_grant' do
    let(:user_id) { '1' }
    let(:channel_id) { '2' }
    let(:start_date) { '2015/01/01' }
    let(:end_date) { '2020/01/01' }

    let(:twirp_response) do
      data = Subs::PreviewTenureResponse.new(
        owner_id: user_id,
        item_id: channel_id,
        domain: Chronobreak::Tenure::SUB_DOMAIN,
        streak_value: 1,
        tenure_value: 1
      )
      Twirp::ClientResp.new(data, nil)
    end

    before(:each) do
      expect(described_class.twirp_client).to receive(:preview_tenure)
        .with(
          owner_id: user_id,
          item_id: channel_id,
          domain: Chronobreak::Tenure::SUB_DOMAIN,
          start: described_class.time_to_protobuf_timestamp(start_date),
          end: described_class.time_to_protobuf_timestamp(end_date),
          tenure_date: described_class.time_to_protobuf_timestamp(Time.now.to_s)
        )
        .and_return(twirp_response)
    end

    it 'calls previewtenure with new grant' do
      described_class.preview_tenure_with_grant(
        user_id,
        channel_id,
        start_date,
        end_date
      )
    end
  end

  describe 'delete_override_grant' do
    let(:user_id) {'1'}
    let(:channel_id) {'2'}
    let(:origin_id) {'3'}
    let(:domain) { Chronobreak::Tenure::SUB_DOMAIN }

    let(:twirp_response) do
      data = Subs::DeleteOverrideGrantResponse.new
      Twirp::ClientResp.new(data, nil)
    end

    before(:each) do
      expect(described_class.twirp_client).to receive(:delete_override_grant)
        .with(
          owner_id: user_id,
          item_id: channel_id,
          origin_id: origin_id,
          domain: domain
        )
        .and_return(twirp_response)
    end

    it 'deletes an override grant' do
      described_class.delete_override_grant(
        user_id,
        channel_id,
        origin_id,
        domain
      )
    end
  end

  describe 'upsert_override_grant' do
    let(:user_id) { '1' }
    let(:channel_id) { '2' }
    let(:start_date) { '2015/01/01' }
    let(:end_date) { '2020/01/01' }

    let(:twirp_response) do
      data = Subs::UpsertGrantResponse.new
      Twirp::ClientResp.new(data, nil)
    end

    before(:each) do
      expect(described_class.twirp_client).to receive(:upsert_grant)
        .with(
          owner_id: user_id,
          item_id: channel_id,
          origin_id: Time.now.to_s,
          domain: Chronobreak::Tenure::SUB_DOMAIN,
          start: described_class.time_to_protobuf_timestamp(start_date),
          end: described_class.time_to_protobuf_timestamp(end_date),
          action: Chronobreak::Tenure::OVERRIDE
        )
        .and_return(twirp_response)
    end

    it 'upserts a grant' do
      described_class.upsert_override_grant(
        user_id,
        channel_id,
        start_date,
        end_date
      )
    end
  end

  describe 'find_tenure' do
    let(:user_id) { '1' }
    let(:channel_id) { '2' }
    let(:twirp_response) do
      data = Subs::ReadTenureResponse.new(
        owner_id: user_id,
        item_id: channel_id,
        domain: Chronobreak::Tenure::SUB_DOMAIN,
        tenure_value: 2,
        tenure_method: Chronobreak::Tenure::TENURE_METHODS[:CUMULATIVE],
        start: Chronobreak::Tenure.time_to_protobuf_timestamp(Time.new(2019, 1, 1).to_s),
        end: Chronobreak::Tenure.time_to_protobuf_timestamp(Time.new(2019, 2, 1).to_s)
      )
      Twirp::ClientResp.new(data, nil)
    end

    before(:each) do
      expect(described_class.twirp_client).to receive(:read_tenure)
        .with(
          owner_id: user_id,
          item_id: channel_id,
          domain: Chronobreak::Tenure::SUB_DOMAIN,
          tenure_method: Chronobreak::Tenure::TENURE_METHODS[:CUMULATIVE],
          tenure_date: Chronobreak::Tenure.time_to_protobuf_timestamp(Time.now.to_s)
        )
        .and_return(twirp_response)
    end

    it 'finds tenure' do
      resp = described_class.find_tenure(
        user_id,
        channel_id,
        Chronobreak::Tenure::SUB_DOMAIN,
        Chronobreak::Tenure::TENURE_METHODS[:CUMULATIVE]
      )

      expect(resp.owner_id).to eql(user_id)
      expect(resp.item_id).to eql(channel_id)
      expect(resp.domain).to eql(Chronobreak::Tenure::SUB_DOMAIN)
      expect(resp.tenure_value).to eql(2)
      expect(resp.tenure_method).to eql(:CUMULATIVE)
      expect(resp.start.to_i).to eql(Time.new(2019, 1, 1).to_i)
      expect(resp.end.to_i).to eql(Time.new(2019, 2, 1).to_i)
    end
  end

  describe 'find_tenures' do
    let(:user_id) { '1' }
    let(:channel_id) { '2' }
    let(:cumulative_tenure) do
      {
        owner_id: user_id,
        item_id: channel_id,
        domain: Chronobreak::Tenure::SUB_DOMAIN,
        value: 2,
        method: Chronobreak::Tenure::TENURE_METHODS[:CUMULATIVE],
        start: Chronobreak::Tenure.time_to_protobuf_timestamp(Time.new(2019, 1, 1).to_s),
        end: Chronobreak::Tenure.time_to_protobuf_timestamp(Time.new(2019, 2, 1).to_s)
      }
    end
    let(:streak_tenure) do
      {
        owner_id: user_id,
        item_id: channel_id,
        domain: Chronobreak::Tenure::SUB_DOMAIN,
        value: 2,
        method: Chronobreak::Tenure::TENURE_METHODS[:STREAK],
        start: Chronobreak::Tenure.time_to_protobuf_timestamp(Time.new(2019, 1, 1).to_s),
        end: Chronobreak::Tenure.time_to_protobuf_timestamp(Time.new(2019, 2, 1).to_s)
      }
    end

    let(:twirp_cumulative_response) do
      data = Subs::ReadTenuresResponse.new(tenures: [cumulative_tenure])
      Twirp::ClientResp.new(data, nil)
    end

    let(:twirp_streak_response) do
      data = Subs::ReadTenuresResponse.new(tenures: [streak_tenure])
      Twirp::ClientResp.new(data, nil)
    end

    it 'finds tenures' do
      expect(described_class.twirp_client).to receive(:read_tenures)
        .with({
          owner_id: user_id,
          item_id: channel_id,
          domain: Chronobreak::Tenure::SUB_DOMAIN,
          tenure_method: Chronobreak::Tenure::TENURE_METHODS[:CUMULATIVE]
        }).and_return(twirp_cumulative_response)

      resp = described_class.find_tenures(
        user_id,
        channel_id,
        Chronobreak::Tenure::SUB_DOMAIN,
        Chronobreak::Tenure::TENURE_METHODS[:CUMULATIVE]
      )

      resp_tenure = resp.tenures[0]

      expect(resp_tenure.owner_id).to eql(user_id)
      expect(resp_tenure.item_id).to eql(channel_id)
      expect(resp_tenure.domain).to eql(Chronobreak::Tenure::SUB_DOMAIN)
      expect(resp_tenure.value).to eql(2)
      expect(resp_tenure['method']).to eql(:CUMULATIVE)
      expect(resp_tenure.start.seconds).to eql(Time.new(2019, 1, 1).to_i)
      expect(resp_tenure.end.seconds).to eql(Time.new(2019, 2, 1).to_i)
    end

    it 'finds tenures' do
      expect(described_class.twirp_client).to receive(:read_tenures)
        .with({
          owner_id: user_id,
          item_id: channel_id,
          domain: Chronobreak::Tenure::SUB_DOMAIN,
          tenure_method: Chronobreak::Tenure::TENURE_METHODS[:STREAK]
        }).and_return(twirp_streak_response)

      resp = described_class.find_tenures(
        user_id,
        channel_id,
        Chronobreak::Tenure::SUB_DOMAIN,
        Chronobreak::Tenure::TENURE_METHODS[:STREAK]
      )

      resp_tenure = resp.tenures[0]

      expect(resp_tenure.owner_id).to eql(user_id)
      expect(resp_tenure.item_id).to eql(channel_id)
      expect(resp_tenure.domain).to eql(Chronobreak::Tenure::SUB_DOMAIN)
      expect(resp_tenure.value).to eql(2)
      expect(resp_tenure['method']).to eql(:STREAK)
      expect(resp_tenure.start.seconds).to eql(Time.new(2019, 1, 1).to_i)
      expect(resp_tenure.end.seconds).to eql(Time.new(2019, 2, 1).to_i)
    end
  end

  describe 'find_grants' do
    let(:user_id) { '1' }
    let(:channel_id) { '2' }

    let(:params) do
      {
        user_id: user_id,
        channel_id: channel_id,
        domain: domain
      }
    end

    let(:grants) do
      [
        {
          id: 'subChannel:122375217:232649790',
          owner_id: '232649790',
          domain: 'subChannel',
          item_id: '122375217',
          origin: 'amzn1.twitch.payments.order.fc911b8d-79f4-4151-8f25-10977faf0ee6',
          action: 'OVERRIDE',
          start: {
            seconds: 1_533_080_726,
            nanos: 0
          },
          end: {
            seconds: 1_535_759_126,
            nanos: 0
          },
          updated_at: {
            seconds: -62_135_596_800,
            nanos: 0
          },
          created_at: {
            seconds: -62_135_596_800,
            nanos: 0
          }
        }
      ]
    end

    let(:twirp_response) do
      data = Subs::ReadGrantsResponse.new grants: grants
      Twirp::ClientResp.new(data, nil)
    end

    before(:each) do
      expect(described_class.twirp_client).to receive(:read_grants)
        .with({
          owner_id: user_id,
          item_id: channel_id,
          domain: Chronobreak::Tenure::SUB_DOMAIN
        })
        .and_return(twirp_response)
    end
    it 'finds grants' do
      req_grant = grants[0]
      resp_grants = described_class.find_grants(user_id, channel_id, Chronobreak::Tenure::SUB_DOMAIN).grants
      resp_grant = resp_grants[0]
      expect(resp_grant.id).to eql(req_grant[:id])
      expect(resp_grant.owner_id).to eql(req_grant[:owner_id])
      expect(resp_grant.domain).to eql(req_grant[:domain])
      expect(resp_grant.item_id).to eql(req_grant[:item_id])
      expect(resp_grant.origin).to eql(req_grant[:origin])
      expect(resp_grant.action).to eql(req_grant[:action])
      expect(resp_grant.start.seconds).to eql(req_grant[:start][:seconds])
      expect(resp_grant.end.seconds).to eql(req_grant[:end][:seconds])
      expect(resp_grant.updated_at.seconds).to eql(req_grant[:updated_at][:seconds])
      expect(resp_grant.created_at.seconds).to eql(req_grant[:created_at][:seconds])
    end
  end
end