package com.rthoni.intellij.codefromds.dbo.options;

import com.intellij.database.psi.DbDataSource;
import com.rthoni.intellij.codefromds.business.DataSourcesBusiness;
import com.rthoni.intellij.codefromds.business.Helper;
import com.rthoni.intellij.codefromds.dbo.template.ColumnDataSourceDbo;
import com.rthoni.intellij.codefromds.dbo.template.DataSourceDbo;
import com.rthoni.intellij.codefromds.dbo.template.StoredProcedureDbo;
import com.rthoni.intellij.codefromds.dbo.template.TableDataSourceDbo;
import org.json.JSONArray;
import org.json.JSONObject;

import java.io.File;
import java.util.HashMap;

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

    private DataSourceDbo _dataSource;

    private String _dataSourceRelativePath;

    private String _modelsRelativePath;

    private String _dataSourceTemplateRelativePath;

    private String _modelsTemplateRelativePath;

    private String _configAbsolutePath;

    private String _filesExtension;

    private String _castFileRelativePath;

    public GenerateOptions(DataSourceDbo dataSource, String configAbsolutePath) {
        _filesExtension = "cs";
        _dataSourceRelativePath = "DataAccess" + File.separator + "DatabaseContext." + _filesExtension;
        _modelsRelativePath = "DataAccess" + File.separator + "Models";
        _dataSourceTemplateRelativePath = "DataAccess" + File.separator + "code-from-ds" + File.separator + "DataSource.twig";
        _modelsTemplateRelativePath = "DataAccess" + File.separator + "code-from-ds" + File.separator + "Models.twig";
        _configAbsolutePath = configAbsolutePath;
        _castFileRelativePath = "DataAccess" + File.separator + "code-from-ds" + File.separator + "types-cast.json";
        _dataSource = dataSource;
    }

    public HashMap<String, Object> toMap()
    {
        HashMap<String, Object> map = new HashMap<>();

        map.put("dataSourceRelativePath", _dataSourceRelativePath);
        map.put("modelsRelativePath", _modelsRelativePath);
        map.put("dataSourceTemplateRelativePath", _dataSourceTemplateRelativePath);
        map.put("modelsTemplateRelativePath", _modelsTemplateRelativePath);
        map.put("filesExtension", _filesExtension);
        map.put("castFileRelativePath", _castFileRelativePath);
        JSONObject selectionObj = new JSONObject();
        selectionObj.put("source", _dataSource.getName());
        JSONArray tablesObj = new JSONArray();
        selectionObj.put("tables", tablesObj);
        for (TableDataSourceDbo table : _dataSource.getTables()) {
            JSONObject tableObj = new JSONObject();
            tablesObj.put(tableObj);
            tableObj.put("table", table.getName());

            JSONArray columnsObj = new JSONArray();
            tableObj.put("columns", columnsObj);
            for (ColumnDataSourceDbo column : table.getColumns()) {
                JSONObject columnObj = new JSONObject();
                columnsObj.put(columnObj);
                columnObj.put("column", column.getName());
                columnObj.put("selected", column.isSelected());
            }
        }

        JSONArray spsObj = new JSONArray();
        selectionObj.put("storedProcedures", spsObj);
        for (StoredProcedureDbo sp : _dataSource.getStoredProcedures()) {
            JSONObject spObj = new JSONObject();
            spsObj.put(spObj);
            spObj.put("storedProcedure", sp.getFullName());
            spObj.put("selected", sp.isSelected());
        }

        map.put("selection", selectionObj);

        return map;
    }

    public void fromJson(JSONObject json)
    {
        _dataSourceRelativePath = Helper.getJsonString(json, "dataSourceRelativePath");
        _modelsRelativePath = Helper.getJsonString(json, "modelsRelativePath");
        _dataSourceTemplateRelativePath = Helper.getJsonString(json, "dataSourceTemplateRelativePath");
        _modelsTemplateRelativePath = Helper.getJsonString(json, "modelsTemplateRelativePath");
        _filesExtension = Helper.getJsonString(json, "filesExtension");
        _castFileRelativePath = Helper.getJsonString(json, "castFileRelativePath");
        JSONObject selectionObj = json.optJSONObject("selection");
        if (selectionObj != null) {
            JSONArray tablesObj = selectionObj.optJSONArray("tables");
            if (tablesObj != null) {
                for (int i = 0; i < tablesObj.length(); ++i) {
                    JSONObject tableObj = tablesObj.optJSONObject(i);
                    if (tableObj != null) {
                        TableDataSourceDbo table = _dataSource.findTable(tableObj.getString("table"));
                        if (table != null) {
                            JSONArray columnsObj = tableObj.optJSONArray("columns");
                            if (columnsObj != null) {
                                for (int j = 0; j < columnsObj.length(); ++j) {
                                    JSONObject columnObj = columnsObj.optJSONObject(j);
                                    if (columnObj != null) {
                                        ColumnDataSourceDbo column = table.findColumn(columnObj.getString("column"));
                                        if (column != null) {
                                            column.setSelected(columnObj.getBoolean("selected"));
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            JSONArray spsObj = selectionObj.optJSONArray("storedProcedures");
            if (spsObj != null) {
                for (int i = 0; i < spsObj.length(); ++i) {
                    JSONObject spObj = spsObj.optJSONObject(i);
                    if (spObj != null) {
                        StoredProcedureDbo sp = _dataSource.findStoredProcedure(spObj.getString("storedProcedure"));
                        if (sp != null) {
                            sp.setSelected(spObj.getBoolean("selected"));
                        }
                    }
                }
            }
        }
    }

    public DataSourceDbo getDataSource() {
        return _dataSource;
    }

    public String getModelsRelativePath() {
        return _modelsRelativePath;
    }

    public void setModelsRelativePath(String modelsRelativePath) {
        _modelsRelativePath = modelsRelativePath;
    }

    public String getDataSourceTemplateRelativePath() {
        return _dataSourceTemplateRelativePath;
    }

    public void setDataSourceTemplateRelativePath(String dataSourceTemplateRelativePath) {
        _dataSourceTemplateRelativePath = dataSourceTemplateRelativePath;
    }

    public String getModelsTemplateRelativePath() {
        return _modelsTemplateRelativePath;
    }

    public void setModelsTemplateRelativePath(String modelsTemplateRelativePath) {
        _modelsTemplateRelativePath = modelsTemplateRelativePath;
    }

    public String getConfigAbsolutePath() {
        return _configAbsolutePath;
    }

    public void setConfigAbsolutePath(String configAbsolutePath) {
        _configAbsolutePath = configAbsolutePath;
    }

    public String getFilesExtension() {
        return _filesExtension;
    }

    public void setFilesExtension(String filesExtension) {
        _filesExtension = filesExtension;
    }

    public String getCastFileRelativePath() {
        return _castFileRelativePath;
    }

    public void setCastFileRelativePath(String castFileRelativePath) {
        _castFileRelativePath = castFileRelativePath;
    }

    public String getDataSourceRelativePath() {
        return _dataSourceRelativePath;
    }

    public void setDataSourceRelativePath(String dataSourceRelativePath) {
        _dataSourceRelativePath = dataSourceRelativePath;
    }
}
