package com.rthoni.intellij.codefromds.business;

import com.intellij.database.model.DasRoutine;
import com.intellij.database.psi.DbDataSource;
import com.intellij.database.psi.DbPsiFacade;
import com.intellij.database.psi.DbRoutine;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import org.json.JSONArray;
import org.json.JSONObject;

import javax.sql.DataSource;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Vector;
import java.util.stream.Collectors;

/**
 * Created by robin on 11/15/16.
 */
public abstract class Helper {

    public static List<DbRoutine> getRoutines(DbDataSource dataSource)
    {
        List<DbRoutine> routines = new Vector<>();
        dataSource.getModel().traverser().forEach(dasObject ->
        {
            if (dasObject instanceof DbRoutine) {
                routines.add((DbRoutine) dasObject);
            }
        });
        return routines;
    }

    public static List<DbDataSource> getDataSources()
    {
        ProjectManager pm = ProjectManager.getInstance();
        Project[] projects = pm.getOpenProjects();
        return Arrays.stream(projects).map(project -> DbPsiFacade.getInstance(project).getDataSources())
                .flatMap(Collection::stream).collect(Collectors.toList());
    }

    public static DbDataSource findDataSource(String name)
    {
        return getDataSources().stream().filter(d -> d.getName().equals(name)).findFirst().orElse(null);
    }

    public static JSONObject findInJson(JSONArray tables, String key, String name)
    {
        for (int i = 0; i < tables.length(); ++i) {
            if (tables.getJSONObject(i).getString(key).equals(name)) {
                return tables.getJSONObject(i);
            }
        }
        return null;
    }

//    public static JSONObject findColumnInJson(JSONArray tables, String name)
//    {
//        for (int i = 0; i < tables.length(); ++i) {
//            if (tables.getJSONObject(i).getString("column").equals(name)) {
//                return tables.getJSONObject(i);
//            }
//        }
//        return null;
//    }

    public static String readFile(String path) throws IOException {
        String data = Files.readAllLines(Paths.get(path), StandardCharsets.UTF_8)
                .stream().reduce("", (s1, s2) -> s1 + s2 + "\n");
        if (data.startsWith("\uFEFF")) {
            return data.substring(1);
        }
        return data;
    }

    public static String getJsonString(JSONObject obj, String key, String defaultValue)
    {
        try {
            return obj.getString(key);
        }
        catch (Exception ignored)
        {
            return defaultValue;
        }
    }

    public static String getJsonString(JSONObject obj, String key)
    {
        return getJsonString(obj, key, "");
    }

    public static String getRelativePath(String base, String absolute)
    {
        if (absolute == null || absolute.isEmpty()) {
            return "";
        }
        Path basePath = Paths.get(base);
        Path absolutePath = Paths.get(absolute);
        return basePath.relativize(absolutePath).toString();
    }

    public static String getRelativePath(Project project, String absolute)
    {
        return getRelativePath(project.getBasePath(), absolute);
    }

    public static String getAbsolutePath(String base, String relative)
    {
        return Paths.get(base, relative).toString();
    }

    public static String getAbsolutePath(Project project, String relative)
    {
        return getAbsolutePath(project.getBasePath(), relative);
    }

    public static String pluralize(String str)
    {
        if (str.endsWith("y")) {
            return str.substring(1, str.length() - 1) + "ies";
        }
        return str + "s";
    }
}
