package ru.otus.mobile.guice;

import com.google.inject.AbstractModule;
import com.google.inject.Provides;
import com.google.inject.Singleton;
import ru.otus.mobile.config.MobileConfig;
import ru.otus.mobile.config.TestEmulator;
import ru.otus.mobile.db.DbConfig;

import java.util.Arrays;
import java.util.List;

public final class CoreModule extends AbstractModule {
    @Provides
    @Singleton
    MobileConfig mobileConfig() {
        String appPackage = value("app.package", "APP_PACKAGE", "ru.otus.wishlist");
        String appUrl = value("app.url", "APP_URL", "http://wiremock:8080/wishlist.apk");
        String appiumHost = value("mobile.host", "MOBILE_HOST", "127.0.0.1");
        List<MobileConfig.Emulator> emulators = Arrays.stream(TestEmulator.values())
                .map(emulator -> emulator.toEmulator(appiumHost, appUrl))
                .toList();
        return new MobileConfig(appPackage, appUrl, appiumHost, emulators);
    }

    @Provides
    @Singleton
    DbConfig dbConfig() {
        String url = requiredValue("db.url", "DB_URL");
        String user = requiredValue("db.user", "DB_USER");
        String password = requiredValue("db.password", "DB_PASSWORD");
        return new DbConfig(url, user, password);
    }

    private String requiredValue(String property, String env) {
        String value = value(property, env, null);
        if (value == null) {
            throw new IllegalStateException(
                    "DB config is missing. Provide db.url/db.user/db.password or DB_URL/DB_USER/DB_PASSWORD."
            );
        }
        return value;
    }

    private String value(String property, String env, String defaultValue) {
        String propertyValue = System.getProperty(property);
        if (!isBlank(propertyValue)) {
            return propertyValue;
        }
        String environmentValue = System.getenv(env);
        if (!isBlank(environmentValue)) {
            return environmentValue;
        }
        return defaultValue;
    }

    private boolean isBlank(String value) {
        return value == null || value.trim().isEmpty();
    }
}
