package zmo.technology.lite.core;

import java.lang.reflect.Field;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.annotation.JSONField;
import com.alibaba.fastjson.serializer.SerializerFeature;

import zmo.technology.lite.core.ZeroFolders.ZeroFoldersParser;

public class ZeroCoreStructs {
    public static final String CURACAO_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'";

    protected UUID id;

    @JSONField(format = CURACAO_DATE_FORMAT)
    protected Date createTime;

    @JSONField(format = CURACAO_DATE_FORMAT)
    protected Date updateTime;

    protected JSONObject features;

    @JSONField(deserializeUsing = ZeroFoldersParser.class, serializeUsing = ZeroFoldersParser.class)
    protected ZeroFolders folders;

    public ZeroCoreStructs() {
        super();
        features = new JSONObject();
    }

    public ZeroCoreStructs(ResultSet set) throws SQLException {
        super();

        if (inResultSet(set, "ID"))
            id = UUID.fromString(set.getString("ID"));

        if (inResultSet(set, "CREATE_TIME"))
            createTime = new Date(set.getTimestamp("CREATE_TIME").getTime());

        if (inResultSet(set, "UPDATE_TIME"))
            updateTime = new Date(set.getTimestamp("UPDATE_TIME").getTime());

        if (inResultSet(set, "FEATURES")) {
            features = JSONObject.parseObject(set.getString("FEATURES"));
        }
    }

    public String uuIDString() {
        return id.toString();
    }

    public void reset() {
        id = UUID.randomUUID();
        createTime = new Date();
        updateTime = new Date();
    }

    public void initFolders() throws ZeroException {
        throw new ZeroException(" no support ");
    }

    public String featuresJSONString() {
        return JSONObject.toJSONString(features);
    }

    public static boolean inResultSet(ResultSet set, String columnName) {
        try {
            return set.findColumn(columnName) > 0;
        } catch (Exception e) {
            return false;
        }
    }

    public Map<String, Field> fetchFieldsMap() {
        Class<?> clazz = getClass();
        Map<String, Field> fMap = new HashMap<>();

        while (clazz != null) {
            Field[] fields = clazz.getDeclaredFields();
            for (int i = 0; i < fields.length; i++)
                fMap.put(fields[i].getName(), fields[i]);
            clazz = clazz.getSuperclass();
        }

        return fMap;
    }

    @Override
    public String toString() {
        return JSONObject.toJSONString(this, SerializerFeature.PrettyFormat);
    }

    public String toJSONString() {
        return JSONObject.toJSONString(this);
    }

    public UUID getId() {
        return id;
    }

    public void setId(UUID id) {
        this.id = id;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public Date getUpdateTime() {
        return updateTime;
    }

    public void setUpdateTime(Date updateTime) {
        this.updateTime = updateTime;
    }

    public JSONObject getFeatures() {
        return features;
    }

    public void setFeatures(JSONObject features) {
        this.features = features;
    }

    public ZeroFolders getFolders() throws ZeroException {
        return null;
    }

    public void setFolders(ZeroFolders folders) throws ZeroException {
        throw new ZeroException(" no support ");
    }
}
