# BackendApiLayerImpl.kt

    /*
     * The MIT License
     *
     * Original work sponsored and donated by The Danish Health Data Authority (http://www.sundhedsdatastyrelsen.dk)
     *
     * Copyright (C) 2021 The Danish Health Data Authority (http://www.sundhedsdatastyrelsen.dk)
     *
     *
     * Permission is hereby granted, free of charge, to any person obtaining a copy of
     * this software and associated documentation files (the "Software"), to deal in
     * the Software without restriction, including without limitation the rights to
     * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
     * of the Software, and to permit persons to whom the Software is furnished to do
     * so, subject to the following conditions:
     *
     *
     * The above copyright notice and this permission notice shall be included in all
     * copies or substantial portions of the Software.
     *
     *
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     * SOFTWARE.
     */

    package dk.nsp.api

    import android.content.Context
    import com.squareup.moshi.Moshi
    import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
    import dk.nsp.api.auth.AuthController
    import dk.nsp.api.careplan.CareplanAPI
    import dk.nsp.api.careplan.CareplanControllerImpl
    import dk.nsp.api.careplan.ICareplanController
    import dk.nsp.api.cms.CMSApi
    import dk.nsp.api.cms.CMSControllerImpl
    import dk.nsp.api.cms.ICMSController
    import dk.nsp.api.configuration.ConfigurationApi
    import dk.nsp.api.configuration.ConfigurationControllerImpl
    import dk.nsp.api.configuration.IConfigurationController
    import dk.nsp.api.datacard.DataCardAPI
    import dk.nsp.api.datacard.DataCardControllerImpl
    import dk.nsp.api.datacard.IDataCardController
    import dk.nsp.api.documentation.DocumentationAPI
    import dk.nsp.api.documentation.DocumentationControllerImpl
    import dk.nsp.api.documentation.IDocumentationController
    import dk.nsp.api.jira.IJiraController
    import dk.nsp.api.jira.JiraApi
    import dk.nsp.api.jira.JiraControllerImpl
    import dk.nsp.api.notes.INotesController
    import dk.nsp.api.notes.NotesAPI
    import dk.nsp.api.notes.NotesControllerImpl
    import dk.nsp.api.observations.IObservationsController
    import dk.nsp.api.observations.ObservationsAPI
    import dk.nsp.api.observations.ObservationsControllerImpl
    import dk.nsp.api.util.CustomOkHttpClient
    import dk.nsp.api.util.converters.BigDecimalAdapter
    import dk.nsp.api.util.converters.LocalDateTimeConverter
    import dk.nsp.mingraviditet.api.BuildConfig
    import retrofit2.Retrofit
    import retrofit2.converter.moshi.MoshiConverterFactory

    const val configurationEndpoint = "configuration/v1"
    const val maternityEndpoint = "maternity/v1"
    const val documentationEndpoint = "pdf/v1"

    class BackendApiLayerImpl(context: Context) : IBackendApiLayer {

        override val configurationController: IConfigurationController by lazy {
            ConfigurationControllerImpl(lexiconApi)
        }

        override val careplanController: ICareplanController by lazy {
            CareplanControllerImpl(careplanApi)
        }

        override val maternityDataCardController: IDataCardController by lazy {
            DataCardControllerImpl(dataCardApi)
        }

        override val notesController: INotesController by lazy {
            NotesControllerImpl(notesApi)
        }

        override val observationsController: IObservationsController by lazy {
            ObservationsControllerImpl(observationsApi)
        }

        override val cmsController: ICMSController by lazy {
            CMSControllerImpl(cmsApi)
        }

        override val jiraController: IJiraController by lazy {
            JiraControllerImpl(jiraApi)
        }

        override val documentationController: IDocumentationController by lazy {
            DocumentationControllerImpl(documentationApi)
        }

        private val backendUrl: String = BuildConfig.BackendUrl

        private val authController = AuthController.get(context.applicationContext)

        private val moshi =
            MoshiConverterFactory.create(
                Moshi
                    .Builder()
                    .add(BigDecimalAdapter())
                    .add(LocalDateTimeConverter())
                    .addLast(KotlinJsonAdapterFactory())
                    .build()
            )

        private val backendRetrofitInstance: Retrofit by lazy {
            Retrofit.Builder()
                .baseUrl(backendUrl)
                .addConverterFactory(moshi)
                .client(
                    CustomOkHttpClient.getSecureClientWithAuth(
                        authController
                    )
                )
                .build()
        }

        private val cmsRetrofitInstance: Retrofit by lazy {
            Retrofit.Builder()
                .baseUrl(BuildConfig.cmsBackendUrl)
                .addConverterFactory(moshi)
                .client(CustomOkHttpClient.getClientWithoutAuth())
                .build()
        }

        private val careplanApi by lazy {
            backendRetrofitInstance.create(CareplanAPI::class.java)
        }

        private val dataCardApi by lazy {
            backendRetrofitInstance.create(DataCardAPI::class.java)
        }

        private val notesApi by lazy {
            backendRetrofitInstance.create(NotesAPI::class.java)
        }

        private val observationsApi by lazy {
            backendRetrofitInstance.create(ObservationsAPI::class.java)
        }

        private val jiraApi by lazy {
            backendRetrofitInstance.create(JiraApi::class.java)
        }

        private val documentationApi by lazy {
            backendRetrofitInstance.create(DocumentationAPI::class.java)
        }

        // CMS APIs
        private val cmsApi by lazy {
            cmsRetrofitInstance.create(CMSApi::class.java)
        }

        private val lexiconApi by lazy {
            backendRetrofitInstance.create(
                ConfigurationApi::class.java
            )
        }
    }