package Ġcom . sh eng bo j ia . integer sequences . repository Ċ Ċ import Ġandroid . util . Log Ċ import Ġandroidx . annotation . MainThread Ċ import Ġandroidx . annotation . Worker Thread Ċ import Ġandroidx . lifecycle . LiveData Ċ import Ġandroidx . lifecycle . Mutable LiveData Ċ import Ġandroidx . paging . Paged List Ċ import Ġcom . sh eng bo j ia . integer sequences . api . Oe is Api Ċ import Ġcom . sh eng bo j ia . integer sequences . api . search And Handle Response Ċ import Ġcom . sh eng bo j ia . integer sequences . data . Local Cache Ċ import Ġcom . sh eng bo j ia . integer sequences . model . Int Sequence Ċ Ċ /** Ċ Ġ* ĠOb serves Ġwhen Ġthe Ġuser Ġreaches Ġthe Ġend Ġof Ġlocally Ġcached Ġdata Ġand Ġthen Ġrequests Ġnew Ġdata Ġfrom Ġthe Ġnetwork . Ċ Ġ*/ Ċ class ĠSequence Boundary Callback ( ĊĠĠĠ Ġprivate Ġval Ġquery : ĠString , ĊĠĠĠ Ġprivate Ġval Ġapi : ĠO e is Api , ĊĠĠĠ Ġprivate Ġval Ġcache : ĠLocal Cache Ċ ) Ġ: ĠP aged List . Boundary Callback < Int Sequence >() Ġ{ ĊĊĠĠĠ Ġ// ĠO e is Ġreturns Ġ 1 0 Ġitems Ġper Ġcall , Ġstarts Ġat Ġ 0 ĊĠĠĠ Ġprivate Ġvar Ġlast Requested Item Ġ= Ġ 0 ĊĊĠĠĠ Ġ// Ġmutable Ġversion Ġto Ġpost Ġvalues Ġin ĊĠĠĠ Ġprivate Ġval Ġ_ network State Ġ= ĠMutable LiveData < Network State >() ĊĊĠĠĠ Ġ// Ġimmutable Ġversion Ġexposed Ġfor Ġuse Ġelsewhere Ġin Ġpackage ĊĠĠĠ Ġval Ġnetwork State : ĠLive Data < Network State > ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġ_ network State ĊĊĠĠĠ Ġ/* ĊĠĠĠ Ġprivate Ġval Ġ_ result State Ġ= ĠMutable LiveData < Result State >() ĊĊĠĠĠ Ġval Ġresult State : ĠLive Data < Result State > ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġ_ result State ĊĊĠĠĠ Ġ*/ ĊĊĠĠĠ Ġprivate Ġval Ġ_ total Count Ġ= ĠMutable LiveData < Int >() ĊĊĠĠĠ Ġval Ġtotal Count : ĠLive Data < Int > ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġ_ total Count ĊĊĠĠĠ Ġ// Ġprevent Ġtriggering Ġmultiple Ġrequests Ġbefore Ġresult Ġreturns ĊĠĠĠ Ġprivate Ġvar Ġis Request InProgress Ġ= Ġfalse ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠWhen Ġthe Ġdatabase Ġis Ġempty , Ġqueries Ġbackend Ġfor Ġmore Ġitems . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ MainThread ĊĠĠĠ Ġoverride Ġfun Ġon Zero Items Loaded () Ġ{ ĊĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" on Zero ") ĊĠĠĠĠĠĠĠ Ġrequest And SaveData ( query ) Ġ{ Ġsequences , Ġcount Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġin Ġbg Ġthread Ġnow ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ_ total Count . post Value ( count ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrequest Success ( sequences ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" on Zero Ġtotal Ġcount : Ġ${ total Count . value }") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠWhen Ġthe Ġend Ġitem Ġof Ġthe Ġlist Ġin Ġthe Ġdb Ġis Ġloaded , Ġqueries Ġfor Ġmore Ġitems Ġfrom Ġbackend . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ MainThread ĊĠĠĠ Ġoverride Ġfun Ġon Item At End Loaded ( item At End : ĠInt Sequence ) Ġ{ ĊĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" on Item At End Loaded Ġ${ total Count . value } Ġ$ last Requested Item ") ĊĠĠĠĠĠĠĠ Ġif Ġ( last Requested Item Ġ> Ġtotal Count . value Ġ?: Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġrequest And SaveData ( query ) Ġ{ Ġsequences , Ġ_ Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrequest Success ( sequences ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/* ĊĠĠĠ Ġprivate Ġfun Ġinitial Request ( query : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( is Request InProgress ) Ġreturn ĊĊĠĠĠĠĠĠĠ Ġ_ network State . value Ġ= ĠNetwork State . LOADING ĊĠĠĠĠĠĠĠ Ġis Request InProgress Ġ= Ġtrue ĊĠĠĠĠĠĠĠ Ġsearch And Handle Response ( api , Ġquery , Ġlast Requested Item , Ġ{ Ġsequences , Ġcount Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( sequences . isEmpty () Ġ&& Ġcount Ġ> Ġ 0 ) Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ_ result State . value Ġ= ĠResult State . TOO _ MAN Y _ RESULTS ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( count Ġ== Ġ 0 ) Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ_ result State . value Ġ= ĠResult State . NO _ RESULTS ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ_ result State . value Ġ= ĠResult State . NORMAL ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcache . insert ( sequences ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtotal Count Ġ= Ġcount ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlast Requested Item Ġ+= Ġ 1 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis Request InProgress Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ_ network State . value Ġ= ĠNetwork State . LOADED ĊĠĠĠĠĠĠĠ Ġ}, Ġ{ error Msg Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ_ network State . value Ġ= ĠNetwork State . error ( error Msg ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis Request InProgress Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġ}) ĊĊĠĠĠ Ġ} ĊĠĠĠ Ġ*/ ĊĊĠĠĠ Ġ/* ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠOnly Ġcalled Ġon Ġthe Ġinitial Ġcall Ġto Ġthe Ġnetwork . ĠDetermines Ġthe Ġtype Ġof Ġresult Ġreturned Ġby Ġthe Ġnetwork ĊĠĠĠĠ Ġ* Ġfrom Ġthe Ġquery , Ġand Ġsets Ġthe Ġtotal Ġcount Ġof Ġmatching Ġresults . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Worker Thread ĊĠĠĠ Ġprivate Ġfun Ġdetermine Result State ( sequences : ĠList < Int Sequence >, Ġcount : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( sequences . isEmpty () Ġ&& Ġcount Ġ> Ġ 0 ) Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ_ result State . post Value ( Result State . TOO _ MAN Y _ RESULTS ) ĊĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( count Ġ== Ġ 0 ) Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ_ result State . post Value ( Result State . NO _ RESULTS ) ĊĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ_ result State . post Value ( Result State . NORMAL ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ_ total Count . post Value ( count ) ĊĊĠĠĠ Ġ} ĊĠĠĠ Ġ*/ ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠOn Ġthe Ġevent Ġof Ġa Ġsuccessful Ġnetwork Ġrequest , Ġupdate Ġthe Ġindex Ġof Ġlast Ġrequested Ġitem , Ġnetwork Ġstate Ġto Ġloaded , ĊĠĠĠĠ Ġ* Ġand Ġwhether Ġrequest Ġis Ġin Ġprogress . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġsequences Ġlist Ġof Ġ[ Int Sequence ] Ġto Ġinsert Ġinto Ġdb ĊĠĠĠĠ Ġ* Ġ@ param Ġcount Ġnumber Ġof Ġmatching Ġresults Ġas Ġreported Ġby Ġnetwork ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Worker Thread ĊĠĠĠ Ġprivate Ġfun Ġrequest Success ( sequences : ĠList < Int Sequence >) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠTODO : ĠCould Ġdo Ġsomething Ġwith Ġcount , Ġlike Ġcheck Ġif Ġdata Ġhas Ġchanged ĊĠĠĠĠĠĠĠ Ġcache . insert ( sequences ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġupdate Ġstatus ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlast Requested Item Ġ+= Ġ 1 0 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ_ network State . post Value ( Network State . LOADED ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis Request InProgress Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠRequests Ġdata Ġfrom Ġthe ĠApi Ġand Ġinserts Ġthe Ġdata Ġinto Ġthe Ġdb . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġquery Ġto Ġbe Ġsearched ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ MainThread ĊĠĠĠ Ġprivate Ġfun Ġrequest And SaveData ( query : ĠString , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠonSuccess : Ġ( List < Int Sequence >, ĠInt ) Ġ-> ĠUnit ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( is Request InProgress ) Ġreturn ĊĊĠĠĠĠĠĠĠ Ġ_ network State . value Ġ= ĠNetwork State . LOADING ĊĠĠĠĠĠĠĠ Ġis Request InProgress Ġ= Ġtrue ĊĠĠĠĠĠĠĠ Ġsearch And Handle Response ( api , Ġquery , Ġlast Requested Item , Ġ{ Ġsequences , Ġcount Ġ-> ĊĊĠĠĠĠĠĠĠĠĠĠĠ ĠonSuccess ( sequences , Ġcount ) ĊĊĠĠĠĠĠĠĠ Ġ}, Ġ{ Ġerror Msg Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠSafe Ġas ĠLive Data Ġcalls Ġthis Ġon Ġmain Ġthread ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ_ network State . post Value ( Network State . error ( error Msg )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis Request InProgress Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠTAG Ġ= Ġ" Callback Boundary " ĊĠĠĠ Ġ} Ċ }