<commit_before># frozen_string_literal: true

require 'tempfile'
require 'fileutils'

module GobiertoPeople
  module GoogleCalendar
    class CalendarIntegration
      CLIENT_SECRETS_PATH = Rails.root.join('config', 'google_calendar_integration_client_secret.json')
      USERNAME = 'default'
      SCOPE = Google::Apis::CalendarV3::AUTH_CALENDAR_READONLY

      def self.sync_person_events(person)
        new(person).sync!
      end

      def sync!
        set_google_calendar_id!

        received_events_ids = []
        service.list_calendar_lists(max_results: 100).items.each do |calendar|
          if configuration.calendars.present? && configuration.calendars.include?(calendar.id)
            received_events_ids.concat sync_calendar_events(calendar)
          end
        end

        person.events.upcoming.synchronized.each do |event|
          unless received_events_ids.include?(event.external_id)
            event.pending!
          end
        end
      end

      def calendars
        @calendars ||= service.list_calendar_lists(max_results: 100).items
      end

      private

      def initialize(person)
        @person = person
        @configuration = GobiertoCalendars::GoogleCalendarConfiguration.find_by(collection_id: person.calendar.id)

        @service = Google::Apis::CalendarV3::CalendarService.new
        @service.client_options.application_name = person.site.name
        @service.authorization = authorize(person)
      end

      attr_reader :person, :configuration, :service

      def set_google_calendar_id!
        if @configuration.google_calendar_id.nil?
          @configuration.google_calendar_id = calendars.detect{ |c| c.primary? }.id
          @configuration.save
        end
      end

      def sync_calendar_events(calendar)
        received_events_ids = []

        response = service.list_events(calendar.id, always_include_email: true, time_min: GobiertoCalendars.sync_range_start.iso8601)
        response.items.each do |event|
          received_events_ids.push event.id
          next if is_private?(event)

          if is_recurring?(event)
            service.list_event_instances(calendar.id, event.id).items.each_with_index do |event, i|
              sync_event(event, i)
            end
          else
            sync_event(event)
          end
        end

        received_events_ids.compact
      end

      def is_private?(event)
        %w( private confidential ).include?(event.visibility)
      end

      def is_recurring?(event)
        event.recurrence.present?
      end

      def event_attendees(event)
        return [] if event.attendees.nil?

        event.attendees.map do |attendee_attributes|
          {
            name: attendee_attributes.display_name,
            email: attendee_attributes.email,
            person: (attendee_attributes.self? ? person : nil)<commit_msg>Fix recurring events id capturing<commit_after># frozen_string_literal: true

require 'tempfile'
require 'fileutils'

module GobiertoPeople
  module GoogleCalendar
    class CalendarIntegration
      CLIENT_SECRETS_PATH = Rails.root.join('config', 'google_calendar_integration_client_secret.json')
      USERNAME = 'default'
      SCOPE = Google::Apis::CalendarV3::AUTH_CALENDAR_READONLY

      def self.sync_person_events(person)
        new(person).sync!
      end

      def sync!
        set_google_calendar_id!

        received_events_ids = []
        service.list_calendar_lists(max_results: 100).items.each do |calendar|
          if configuration.calendars.present? && configuration.calendars.include?(calendar.id)
            received_events_ids.concat sync_calendar_events(calendar)
          end
        end

        person.events.upcoming.synchronized.each do |event|
          unless received_events_ids.include?(event.external_id)
            event.pending!
          end
        end
      end

      def calendars
        @calendars ||= service.list_calendar_lists(max_results: 100).items
      end

      private

      def initialize(person)
        @person = person
        @configuration = GobiertoCalendars::GoogleCalendarConfiguration.find_by(collection_id: person.calendar.id)

        @service = Google::Apis::CalendarV3::CalendarService.new
        @service.client_options.application_name = person.site.name
        @service.authorization = authorize(person)
      end

      attr_reader :person, :configuration, :service

      def set_google_calendar_id!
        if @configuration.google_calendar_id.nil?
          @configuration.google_calendar_id = calendars.detect{ |c| c.primary? }.id
          @configuration.save
        end
      end

      def sync_calendar_events(calendar)
        received_events_ids = []

        response = service.list_events(calendar.id, always_include_email: true, time_min: GobiertoCalendars.sync_range_start.iso8601)
        response.items.each do |event|
          received_events_ids.push event.id
          next if is_private?(event)

          if is_recurring?(event)
            service.list_event_instances(calendar.id, event.id).items.each_with_index do |event, i|
              received_events_ids.push event.id
              sync_event(event, i)
            end
          else
            sync_event(event)
          end
        end

        received_events_ids
      end

      def is_private?(event)
        %w( private confidential ).include?(event.visibility)
      end

      def is_recurring?(event)
        event.recurrence.present?
      end

      def event_attendees(event)
        return [] if event.attendees.nil?

        event.attendees.map do |attendee_attributes|
          {
            name: attendee_attributes.display_name,
            email: attendee_attributes.email,
            person: (attendee_attributes.self? ? person : nil)
{'fraction_non_alphanumeric': 0.07967507777393709, 'fraction_numerical': 0.00414794331144141, 'mean_word_length': 2.532967032967033, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5012771', 'n_tokens_mistral': 1686, 'n_tokens_neox': 1627, 'n_words': 295}