<commit_before>import { Injectable } from '@angular/core'
import { AppVersion } from '@ionic-native/app-version/ngx'
import { HTTP } from '@ionic-native/http/ngx'

import {
  ARMTDefBranchProd,
  ARMTDefBranchTest,
  DefaultNumberOfNotificationsToSchedule,
  DefaultProtocolEndPoint,
  DefaultProtocolURI,
  DefaultQuestionnaireFormatURI,
  DefaultQuestionnaireTypeURI,
  TEST_ARMT_DEF
} from '../../../assets/data/defaultConfig'
import { StorageKeys } from '../../shared/enums/storage'
import { FirebaseAnalyticsService } from './firebaseAnalytics.service'
import { NotificationService } from './notification.service'
import { SchedulingService } from './scheduling.service'
import { StorageService } from './storage.service'

@Injectable()
export class ConfigService {
  constructor(
    private http: HTTP,
    public storage: StorageService,
    private schedule: SchedulingService,
    private notificationService: NotificationService,
    private appVersion: AppVersion,
    private firebaseAnalytics: FirebaseAnalyticsService
  ) {}

  fetchConfigState(force: boolean) {
    return Promise.all([
      this.storage.get(StorageKeys.CONFIG_VERSION),
      this.storage.get(StorageKeys.SCHEDULE_VERSION),
      this.storage.get(StorageKeys.APP_VERSION),
      this.appVersion.getVersionNumber()
    ]).then(
      ([configVersion, scheduleVersion, storedAppVersion, appVersion]) => {
        return this.pullProtocol().then(response => {
          if (!response) return Promise.reject()
          if (
            configVersion !== response.version ||
            scheduleVersion !== response.version ||
            storedAppVersion !== appVersion ||
            force
          ) {
            this.storage.set(StorageKeys.APP_VERSION, appVersion)
            this.storage.set(StorageKeys.HAS_CLINICAL_TASKS, false)
            const protocolFormated = this.formatPulledProcotol(
              response.protocols
            )
            const scheduledAssessments = []
            const clinicalAssessments = []
            for (let i = 0; i < protocolFormated.length; i++) {
              const clinical =
                protocolFormated[i]['protocol']['clinicalProtocol']
              if (clinical) {
                this.storage.set(StorageKeys.HAS_CLINICAL_TASKS, true)
                clinicalAssessments.push(protocolFormated[i])
              } else {
                scheduledAssessments.push(protocolFormated[i])
              }
            }
            return this.storage
              .set(StorageKeys.CONFIG_VERSION, response.version)
              .then(() => {
                return this.storage
                  .set(
                    StorageKeys.CONFIG_CLINICAL_ASSESSMENTS,
                    clinicalAssessments
                  )
                  .then(() => {
                    console.log('Pulled clinical questionnaire')
                    return this.pullQuestionnaires(
                      StorageKeys.CONFIG_CLINICAL_ASSESSMENTS
                    )
                  })
              })
              .then(() => {
                return this.storage
                  .set(StorageKeys.CONFIG_ASSESSMENTS, scheduledAssessments)
                  .then(() => {
                    console.log('Pulled questionnaire')
                    return this.pullQuestionnaires(
                      StorageKeys.CONFIG_ASSESSMENTS
                    )
                  })
              })
              .then(() => this.schedule.generateSchedule(true))
              .then(() => this.rescheduleNotifications())
              .then(() =>
                Promise.all([
                  this.storage.get(StorageKeys.PARTICIPANTLOGIN),
                  this.getProjectName(),
                  this.storage.get(StorageKeys.SOURCEID),
                  this.storage.get(StorageKeys.ENROLMENTDATE),
                  this.storage.get(StorageKeys.PARTICIPANTID)
                ]).then(
                  ([
                    subjectId,
                    projectId,
                    sourceId,
                    enrolmentDate,
                    humanReadableId
                  ]) =>
                    this.firebaseAnalytics.setUserProperties({
                      subjectId: subjectId,
                      projectId: projectId,
                      sourceId: sourceId,
                      enrolmentDate: String(enrolmentDate),
                      humanReadableId: humanReadableId
                    })
                )
              )
              .then(() =>
                this.firebaseAnalytics.logEvent('config_update', {
                  config_version: String(configVersion),
                  schedule_version: String(scheduleVersion),
                  app_version: appVersion
                })
              )
          } else {
            console.log(
              'NO CONFIG UPDATE. Version of protocol.json has not changed.'
            )
            return this.schedule.generateSchedule(false)
          }
        })
      }
    )
  }

  rescheduleNotifications() {
    return this.notificationService.cancelNotifications().then(() => {
      // NOTE: Set notification here too so scheduled everytime the schedule changes too.
      return this.notificationService
        .setNextXNotifications(DefaultNumberOfNotificationsToSchedule)
        .then(() => console.log('NOTIFICATIONS scheduled after config change'))
        .then(() =>
          this.firebaseAnalytics.logEvent('notification_rescheduled', {})
        )
    })
  }

  updateConfigStateOnLanguageChange() {
    return this.pullQuestionnaires(StorageKeys.CONFIG_CLINICAL_ASSESSMENTS)
      .then(() => this.pullQuestionnaires(StorageKeys.CONFIG_ASSESSMENTS))
      .then(() => this.rescheduleNotifications())
  }

  updateConfigStateOnTimezoneChange() {
    return this.schedule
      .generateSchedule(true)
      .then(() => this.rescheduleNotifications())
  }

  pullProtocol() {
    return this.getProjectName().then(projectName => {
      if (!projectName) {
        console.error(
          'Unknown project name : ' + projectName + '. Cannot pull protocols.'
        )
        return Promise.reject()
      }
      const URI = DefaultProtocolEndPoint + projectName + DefaultProtocolURI
      return this.http.get(URI, { responseType: 'text' }).toPromise()
    })
  }

  getProjectName() {
    return this.storage.get(StorageKeys.PROJECTNAME)
  }

  formatPulledProcotol(protocols) {
    const protocolsFormated = protocols
    for (let i = 0; i < protocolsFormated.length; i++) {
      protocolsFormated[i].questionnaire['type'] = DefaultQuestionnaireTypeURI
      protocolsFormated[i].questionnaire[
        'format'
      ] = DefaultQuestionnaireFormatURI
    }
    return protocolsFormated
  }

  retrieveLanguageKeys(questionnaireURI) {
    const langs = []
    for (const key in questionnaireURI) {
      if (key) {
        langs.push(key)
      }
    }
    const langsKeyValEmpty = {}
    for (const val of langs) {
      langsKeyValEmpty[val] = ''<commit_msg>chore: fix merge conflicts<commit_after>import { Injectable } from '@angular/core'
import { AppVersion } from '@ionic-native/app-version/ngx'
import { HTTP } from '@ionic-native/http/ngx'

import {
  ARMTDefBranchProd,
  ARMTDefBranchTest,
  DefaultNumberOfNotificationsToSchedule,
  DefaultProtocolEndPoint,
  DefaultProtocolURI,
  DefaultQuestionnaireFormatURI,
  DefaultQuestionnaireTypeURI,
  TEST_ARMT_DEF
} from '../../../assets/data/defaultConfig'
import { StorageKeys } from '../../shared/enums/storage'
import { FirebaseAnalyticsService } from './firebaseAnalytics.service'
import { NotificationService } from './notification.service'
import { SchedulingService } from './scheduling.service'
import { StorageService } from './storage.service'

@Injectable()
export class ConfigService {
  constructor(
    private http: HTTP,
    public storage: StorageService,
    private schedule: SchedulingService,
    private notificationService: NotificationService,
    private appVersion: AppVersion,
    private firebaseAnalytics: FirebaseAnalyticsService
  ) {}

  fetchConfigState(force: boolean) {
    return Promise.all([
      this.storage.get(StorageKeys.CONFIG_VERSION),
      this.storage.get(StorageKeys.SCHEDULE_VERSION),
      this.storage.get(StorageKeys.APP_VERSION),
      this.appVersion.getVersionNumber()
    ]).then(
      ([configVersion, scheduleVersion, storedAppVersion, appVersion]) => {
        return this.pullProtocol().then(response => {
          if (!response) return Promise.reject()
          if (
            configVersion !== response.version ||
            scheduleVersion !== response.version ||
            storedAppVersion !== appVersion ||
            force
          ) {
            this.storage.set(StorageKeys.APP_VERSION, appVersion)
            this.storage.set(StorageKeys.HAS_CLINICAL_TASKS, false)
            const protocolFormated = this.formatPulledProcotol(
              response.protocols
            )
            const scheduledAssessments = []
            const clinicalAssessments = []
            for (let i = 0; i < protocolFormated.length; i++) {
              const clinical =
                protocolFormated[i]['protocol']['clinicalProtocol']
              if (clinical) {
                this.storage.set(StorageKeys.HAS_CLINICAL_TASKS, true)
                clinicalAssessments.push(protocolFormated[i])
              } else {
                scheduledAssessments.push(protocolFormated[i])
              }
            }
            return this.storage
              .set(StorageKeys.CONFIG_VERSION, response.version)
              .then(() => {
                return this.storage
                  .set(
                    StorageKeys.CONFIG_CLINICAL_ASSESSMENTS,
                    clinicalAssessments
                  )
                  .then(() => {
                    console.log('Pulled clinical questionnaire')
                    return this.pullQuestionnaires(
                      StorageKeys.CONFIG_CLINICAL_ASSESSMENTS
                    )
                  })
              })
              .then(() => {
                return this.storage
                  .set(StorageKeys.CONFIG_ASSESSMENTS, scheduledAssessments)
                  .then(() => {
                    console.log('Pulled questionnaire')
                    return this.pullQuestionnaires(
                      StorageKeys.CONFIG_ASSESSMENTS
                    )
                  })
              })
              .then(() => this.schedule.generateSchedule(true))
              .then(() => this.rescheduleNotifications())
              .then(() =>
                Promise.all([
                  this.storage.get(StorageKeys.PARTICIPANTLOGIN),
                  this.getProjectName(),
                  this.storage.get(StorageKeys.SOURCEID),
                  this.storage.get(StorageKeys.ENROLMENTDATE),
                  this.storage.get(StorageKeys.PARTICIPANTID)
                ]).then(
                  ([
                    subjectId,
                    projectId,
                    sourceId,
                    enrolmentDate,
                    humanReadableId
                  ]) =>
                    this.firebaseAnalytics.setUserProperties({
                      subjectId: subjectId,
                      projectId: projectId,
                      sourceId: sourceId,
                      enrolmentDate: String(enrolmentDate),
                      humanReadableId: humanReadableId
                    })
                )
              )
              .then(() =>
                this.firebaseAnalytics.logEvent('config_update', {
                  config_version: String(configVersion),
                  schedule_version: String(scheduleVersion),
                  app_version: appVersion
                })
              )
          } else {
            console.log(
              'NO CONFIG UPDATE. Version of protocol.json has not changed.'
            )
            return this.schedule.generateSchedule(false)
          }
        })
      }
    )
  }

  rescheduleNotifications() {
    return this.notificationService.cancelNotifications().then(() => {
      // NOTE: Set notification here too so scheduled everytime the schedule changes too.
      return this.notificationService
        .setNextXNotifications(DefaultNumberOfNotificationsToSchedule)
        .then(() => console.log('NOTIFICATIONS scheduled after config change'))
        .then(() =>
          this.firebaseAnalytics.logEvent('notification_rescheduled', {})
        )
    })
  }

  updateConfigStateOnLanguageChange() {
    return this.pullQuestionnaires(StorageKeys.CONFIG_CLINICAL_ASSESSMENTS)
      .then(() => this.pullQuestionnaires(StorageKeys.CONFIG_ASSESSMENTS))
      .then(() => this.rescheduleNotifications())
  }

  updateConfigStateOnTimezoneChange() {
    return this.schedule
      .generateSchedule(true)
      .then(() => this.rescheduleNotifications())
  }

  pullProtocol() {
    return this.getProjectName().then(projectName => {
      if (!projectName) {
        console.error(
          'Unknown project name : ' + projectName + '. Cannot pull protocols.'
        )
        return Promise.reject()
      }
      const URI = DefaultProtocolEndPoint + projectName + DefaultProtocolURI
      return this.http.get(URI, { responseType: 'text' }, '').then(res => {
        return JSON.parse(res.data)
      })
    })
  }

  getProjectName() {
    return this.storage.get(StorageKeys.PROJECTNAME)
  }

  formatPulledProcotol(protocols) {
    const protocolsFormated = protocols
    for (let i = 0; i < protocolsFormated.length; i++) {
      protocolsFormated[i].questionnaire['type'] = DefaultQuestionnaireTypeURI
      protocolsFormated[i].questionnaire[
        'format'
      ] = DefaultQuestionnaireFormatURI
    }
    return protocolsFormated
  }

  retrieveLanguageKeys(questionnaireURI) {
    const langs = []
    for (const key in questionnaireURI) {
      if (key) {
        langs.push(key)
      }
    }
    const langsKeyValEmpty = {}
    for (const val of langs) {
      langsKeyValEmpty[val] = ''
{'fraction_non_alphanumeric': 0.09699376063528077, 'fraction_numerical': 0.0002836074872376631, 'mean_word_length': 1.8927399507793272, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 40, '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': '1200077', 'n_tokens_mistral': 3668, 'n_tokens_neox': 3487, 'n_words': 613}