package Ġorg . sage b ion etwork s . bridge . k mm . shared . repo Ċ Ċ import Ġco . touch lab . state ly . ensure Never Frozen Ċ import Ġio . ktor . client .* Ċ import Ġio . ktor . client . features .* Ċ import Ġio . ktor . http .* Ċ import Ġio . ktor . util . network .* Ċ import Ġkotlinx . coroutines . Coroutine Scope Ċ import Ġkotlinx . coroutines . flow . Flow Ċ import Ġkotlinx . coroutines . launch Ċ import Ġkotlinx . datetime . Clock Ċ import Ġkotlinx . datetime . TimeZone Ċ import Ġkotlinx . serialization . Serializable Ċ import Ġkotlinx . serialization . encode ToString Ċ import Ġkotlinx . serialization . json . Json Ċ import Ġorg . sage b ion etwork s . bridge . k mm . shared . apis . Schedules V 2 Api Ċ import Ġorg . sage b ion etwork s . bridge . k mm . shared . cache .* Ċ import Ġorg . sage b ion etwork s . bridge . k mm . shared . models .* Ċ import Ġorg . sage b ion etwork s . bridge . k mm . shared . models . Ad her ence Record List Ċ Ċ class ĠAd her ence Record Repo ( httpClient : ĠHttpClient , Ġdatabase Helper : ĠResource Database Helper , Ġbackground Scope : ĠCor outine Scope ) Ġ: ĊĠĠĠĠĠĠĠ ĠAbstract Resource Repo ( database Helper , Ġresource Type Ġ= ĠResource Type . AD HER ENCE _ RECORD , Ġbackground Scope ) Ġ{ ĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġensure Never Frozen () ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġinternal Ġvar Ġschedule V 2 Api Ġ= ĠS chedules V 2 Api ( ĊĠĠĠĠĠĠĠ ĠhttpClient Ġ= ĠhttpClient ĊĠĠĠ Ġ) ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠGet Ġthe Ġlocally Ġcached Ġ[ Ad her ence Record ] s Ġfor Ġthe Ġspecified Ġ[ instance Ids ]. ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġget Cached Ad her ence Records ( instance Ids : ĠList < String >, Ġstudy Id : ĠString ) Ġ: ĠMap < String , ĠList < Ad her ence Record >> Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġlist : ĠList < Ad her ence Record > Ġ= Ġdatabase . getResources ById s ( instance Ids , Ġresource Type , Ġstudy Id ). map NotNull Ġ{ Ġit . load Resource () Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġlist . groupBy Ġ{ Ġit . instance Guid Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠDownload Ġand Ġcache Ġlocally Ġall Ġ[ Ad her ence Record ] s Ġfor Ġthe Ġgiven Ġstudy . ĊĠĠĠĠ Ġ* ĠFor Ġnow Ġthis Ġonly Ġrequests Ġrecords Ġusing Ġthe Ġcurrent Ġtimestamps . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġsuspend Ġfun Ġload Remote Ad her ence Records ( study Id : ĠString ) Ġ: ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠpageSize Ġ= Ġ 5 0 0 ĊĠĠĠĠĠĠĠ Ġvar Ġpage Offset Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġvar Ġad her ence Records Search Ġ= ĠAd her ence Records Search ( sort Order Ġ= ĠSort Order . DESC , ĠpageSize Ġ= ĠpageSize , Ġinclude Repe ats Ġ= Ġtrue , Ġcurrent Timestamp s Only Ġ= Ġtrue ) ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdo Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcur PageSize Ġ= ĠpageSize ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrecord Result Ġ= Ġload And Cache Results ( study Id , Ġad her ence Records Search ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpage Offset += ĠpageSize ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġad her ence Records Search Ġ= Ġad her ence Records Search . copy ( offset By Ġ= Ġpage Offset ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġwhile Ġ( cur PageSize Ġ+ ĠpageSize Ġ< Ġrecord Result . total ) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( throwable : ĠThrowable ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprintln ( throwable ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġload And Cache Results ( study Id : ĠString , Ġad her ence Records Search : ĠAd her ence Records Search ) Ġ: ĠAd her ence Record List Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġrecords Result Ġ= Ġschedule V 2 Api . search For Ad her ence Records ( study Id , Ġad her ence Records Search ) ĊĠĠĠĠĠĠĠ Ġfor Ġ( record Ġin Ġrecords Result . items ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinsert Update ( record , Ġstudy Id ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġrecords Result ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġinsert Update ( ad her ence Record : ĠAd her ence Record , Ġstudy Id : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġjson Ġ= ĠJson . encode ToString ( ad her ence Record ) ĊĠĠĠĠĠĠĠ Ġval Ġresource Ġ= ĠResource ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġidentifier Ġ= Ġad her ence Record . instance Guid , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsecondary Id Ġ= Ġad her ence Record . started On . toString (), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtype Ġ= Ġresource Type , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstudy Id Ġ= Ġstudy Id , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġjson Ġ= Ġjson , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlast Update Ġ= ĠClock . System . now (). to Epoch Milliseconds (), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstatus Ġ= ĠResource Status . SUCCESS , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġneed Save Ġ= Ġtrue ) ĊĠĠĠĠĠĠĠ Ġdatabase . insert Update Resource ( resource ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠUpdate Ġthe Ġlocal Ġcache Ġwith Ġthe Ġspecified Ġ[ Ad her ence Record ] Ġand Ġtrigger Ġa Ġbackground Ġcall ĊĠĠĠĠ Ġ* Ġto Ġsave Ġto ĠBridge Ġserver . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġcreate Update Ad her ence Record ( ad her ence Record : ĠAd her ence Record , Ġstudy Id : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġinsert Update ( ad her ence Record , Ġstudy Id ) ĊĠĠĠĠĠĠĠ Ġbackground Scope . launch () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprocess Updates ( study Id ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠSave Ġany Ġlocally Ġcached Ġ[ Ad her ence Record ] s Ġthat Ġhaven 't Ġbeen Ġuploaded Ġto ĠBridge Ġserver . ĊĠĠĠĠ Ġ* ĠAny Ġfailures Ġwill Ġremain Ġin Ġa Ġneed Save Ġstate Ġand Ġbe Ġtried Ġagain Ġthe Ġnext Ġtime . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġprocess Updates ( study Id : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġresources To Upload Ġ= Ġdatabase . getResources Need Save ( resourceType , Ġstudy Id ) ĊĠĠĠĠĠĠĠ Ġval Ġrecords : ĠList < Ad her ence Record > Ġ= Ġresources To Upload . map NotNull Ġ{ Ġit . load Resource () Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( records . isEmpty ()) Ġreturn ĊĠĠĠĠĠĠĠ Ġvar Ġstatus Ġ= ĠResource Status . FAILED ĊĠĠĠĠĠĠĠ Ġvar Ġneed Save Ġ= Ġtrue ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġschedule V 2 Api . update Ad her ence Records ( study Id , Ġrecords ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstatus Ġ= ĠResource Status . SUCCESS ĊĠĠĠĠĠĠĠĠĠĠĠ Ġneed Save Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( throwable : ĠThrowable ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprintln ( throwable ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( throwable ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠResponse Exception Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( throwable . response . status ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠHttpStatusCode . Unauthorized Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġ 4 0 1 Ġun authorized ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠUser Ġhasn 't Ġauthenticated Ġor Ġre - auth Ġhas Ġfailed . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠHttpStatusCode . G one Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// 4 1 0 ĠG one ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThe Ġversion Ġof Ġthe Ġclient Ġmaking Ġthe Ġrequest Ġno Ġlonger Ġhas Ġaccess Ġto Ġthis Ġservice . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThe Ġuser Ġmust Ġupdate Ġtheir Ġapp Ġin Ġorder Ġto Ġcontinue Ġusing ĠBridge . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠHttpStatusCode . Precondition Failed Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// 4 1 2 ĠNot Ġconsent ed ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠUn resolved Address Exception Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Internet Ġconnection Ġerror ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstatus Ġ= ĠResource Status . RETRY ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġfor Ġ( resource Ġin Ġresources To Upload ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġto Update Ġ= Ġresource . copy ( status Ġ= Ġstatus , Ġneed Save Ġ= Ġneed Save ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdatabase . insert Update Resource ( to Update ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ}