package ru.kirillius.pf.sdn.External.API;

import org.json.JSONObject;
import org.json.JSONTokener;
import ru.kirillius.json.JSONUtility;
import ru.kirillius.pf.sdn.core.Context;
import ru.kirillius.pf.sdn.core.Networking.NetworkResourceBundle;
import ru.kirillius.pf.sdn.core.Subscription.RepositoryConfig;
import ru.kirillius.pf.sdn.core.Subscription.SubscriptionProvider;
import ru.kirillius.utils.logging.SystemLogger;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * Subscription provider that pulls JSON resource bundles from a Git repository cache.
 */
public class LocalFilesystemSubscription implements SubscriptionProvider {
    private final static String CTX = LocalFilesystemSubscription.class.getSimpleName();
    private final Context context;

    /**
     * Creates the provider using the shared application context.
     */
    public LocalFilesystemSubscription(Context context) {
        this.context = context;
    }

    /**
     * Clones or updates the configured repository and loads resource bundles from the {@code resources} directory.
     */
    @Override
    public Map<String, NetworkResourceBundle> getResources(RepositoryConfig config) {
        try {
            var resourcesDir = new File(config.getSource());
            if (!resourcesDir.exists()) {
                SystemLogger.error(resourcesDir + " is not exist directory", CTX);
                return Collections.emptyMap();
            }
            if(!config.getScript().isBlank()){
                try (var shell = new ShellExecutor(ShellExecutor.Config.builder().useSSH(false).build())) {
                    var result = shell.executeCommand(new String[]{
                            config.getScript(),
                            config.getSource()
                    });
                    SystemLogger.message("Shell command execution result:"+result, CTX);
                }
            }
            return scanLocalDirectory(resourcesDir);

        } catch (Exception e) {
            SystemLogger.error("Error while reading local FS repository", CTX, e);
            throw new RuntimeException(e);
        }
    }

    public static Map<String, NetworkResourceBundle> scanLocalDirectory(File resourcesDir) throws IOException {
        var map = new HashMap<String, NetworkResourceBundle>();
        for (var file : Objects.requireNonNull(resourcesDir.listFiles())) {
            try (var stream = new FileInputStream(file)) {
                var name = file.getName();
                if (!name.endsWith(".json")) {
                    continue;
                }
                var bundle = JSONUtility.deserializeStructure(new JSONObject(new JSONTokener(stream)), NetworkResourceBundle.class);
                map.put(name.substring(0, name.length() - 5), bundle);
            }
        }

        return map;
    }
}
