// Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

import 'dart:async';

import 'package:architecture_example/data/data_sources/local/favorite_hive_data_source.dart';
import 'package:architecture_example/data/data_sources/local/favorite_mock_data_source.dart';
import 'package:architecture_example/data/data_sources/remote/album_api_data_source_impl.dart';
import 'package:architecture_example/data/data_sources/remote/album_mock_data_source_impl.dart';
import 'package:architecture_example/data/data_sources/remote/photo_api_data_source_impl.dart';
import 'package:architecture_example/data/data_sources/remote/photo_mock_data_source_impl.dart';
import 'package:architecture_example/domain/data_sources/local/favorite_local_data_source.dart';
import 'package:architecture_example/domain/data_sources/remote/album_remote_data_source.dart';
import 'package:architecture_example/domain/data_sources/remote/photo_remote_data_source.dart';
import 'package:get_it/get_it.dart';
import 'package:wyatt_http_client/wyatt_http_client.dart';

final getIt = GetIt.I;

abstract class GetItInitializer {
  static Future<void> _initGlobal() async {}
  static Future<void> _initMocks() async {
    getIt
      ..registerLazySingleton<FavoriteLocalDataSource>(
        FavoriteMockDataSource.new,
      )
      ..registerLazySingleton<PhotoRemoteDataSource>(
        PhotoMockDataSourceImpl.new,
      )
      ..registerLazySingleton<AlbumRemoteDataSource>(
        AlbumMockDataSourceImpl.new,
      );
  }

  static Future<void> _initReal() async {
    getIt
      ..registerLazySingleton<FavoriteLocalDataSource>(
        FavoriteHiveDataSource.new,
      )
      ..registerLazySingleton<MiddlewareClient>(() {
        final Pipeline pipeline = Pipeline()
            .addMiddleware(
              UriPrefixMiddleware(
                protocol: Protocols.https,
                authority: 'jsonplaceholder.typicode.com',
              ),
            )
            .addMiddleware(BodyToJsonMiddleware());
        return MiddlewareClient(pipeline: pipeline);
      })
      ..registerLazySingleton<PhotoRemoteDataSource>(
        () => PhotoApiDataSourceImpl(getIt()),
      )
      ..registerLazySingleton<AlbumRemoteDataSource>(
        () => AlbumApiDataSourceImpl(getIt()),
      );
  }

  static Future<void> run({bool enableMocks = false}) async {
    await _initGlobal();
    enableMocks ? await _initMocks() : await _initReal();

    await getIt.allReady();
  }
}
