package com.ruoyi.ext.api.db;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.Reader;
import java.io.Serializable;
import java.sql.*;
import java.util.ArrayList;
import java.util.Base64;

@SuppressWarnings("unchecked")
public class DBResult implements Serializable
{
    private static final Log logger = LogFactory.getLog(DBResult.class);
    private String ColumnLabelList[] = null;
    private ArrayList fieldList = new ArrayList();
    private int columnTypeList[] = null;
    private int recordCount = 0;

    private boolean successed = false;

    public ArrayList getRowList() {
        return rowList;
    }

    public void setRowList(ArrayList rowList) {
        this.rowList = rowList;
    }

    private String message = "";
    private ArrayList rowList = new ArrayList();
    private boolean hasBinary = false;

    public boolean isHasBinary()
    {
        return hasBinary;
    }

    public String getMessage()
    {
        return message;
    }

    public void setMessage(String message)
    {
        this.message = message;
    }

    public void setSuccessed(boolean successed)
    {
        this.successed = successed;
    }


    public String[] getColumnLabelList()
    {
        return ColumnLabelList;
    }


    public int[] getColumnTypeList()
    {
        return columnTypeList;
    }

    public String[] getAllFieldData(String fieldName)
    {
        fieldName = fieldName.toUpperCase();

        int colIndex = fieldList.indexOf(fieldName);

        if (colIndex == -1)
        {
            logger.error("未发现字段:" + fieldName);
            return null;
        }

        String fieldData[] = new String[recordCount];
        for (int i = 0; i < rowList.size(); i++)
        {
            fieldData[i] = ((String[]) rowList.get(i))[colIndex];
        }

        return fieldData;
    }


    public int getRecordCount()
    {
        return recordCount;
    }

    public boolean isSuccessed()
    {
        return successed;
    }


    public String getString(int rowIndex, int colIndex)
    {
        return ((String[]) rowList.get(rowIndex))[colIndex];

    }


    public String getString(int rowIndex, String fieldName)
    {
        fieldName = fieldName.toUpperCase();

        int colIndex = fieldList.indexOf(fieldName);

        if (colIndex == -1)
        {
            logger.error("未发现字段:" + fieldName);
            return null;
        }

        return ((String[]) rowList.get(rowIndex))[colIndex];

    }

    public void setString(int rowIndex, String fieldName, String value)
    {
        fieldName = fieldName.toUpperCase();

        int colIndex = fieldList.indexOf(fieldName);

        if (colIndex == -1)
        {
            logger.error("未发现字段:" + fieldName);
            return;
        }


        ((String[]) rowList.get(rowIndex))[colIndex] = value;
    }


    public int getInt(int rowIndex, int colIndex)
    {
        String colValue = ((String[]) rowList.get(rowIndex))[colIndex];

        if (colValue.length() > 0)
            return Integer.parseInt(colValue);
        else
            return 0;
    }

    public int getInt(int rowIndex, String fieldName)
    {
        fieldName = fieldName.toUpperCase();
        int colIndex = fieldList.indexOf(fieldName);

        if (colIndex == -1)
        {
            logger.error("未发现字段:" + fieldName);
            return -1;
        }

        String colValue = ((String[]) rowList.get(rowIndex))[colIndex];

        if (colValue.length() > 0)
            return Integer.parseInt(colValue);
        else
            return 0;
    }


    public DBResult()
    {
    }


    public boolean pushResultSet(ResultSet rs)
    {
        int fieldCnt = 0;
        byte[] binaryBytes = null;
        String colValue = "";
        boolean bResult = false;

        Base64.Encoder base64Encoder = Base64.getEncoder();
        java.text.SimpleDateFormat formatter = new java.text.SimpleDateFormat(
                "yyyyMMddHHmmss");


        try
        {
            ResultSetMetaData rsmd = rs.getMetaData();
            fieldCnt = rsmd.getColumnCount();

            ColumnLabelList = new String[fieldCnt];
            columnTypeList = new int[fieldCnt];

            for (int i = 0; i < fieldCnt; i++)
            {
                ColumnLabelList[i] = rsmd.getColumnLabel(i + 1).toUpperCase();
                columnTypeList[i] = rsmd.getColumnType(i + 1);
                fieldList.add(ColumnLabelList[i]);

                if ((columnTypeList[i] == Types.BLOB
                        || columnTypeList[i] == Types.LONGVARBINARY || columnTypeList[i] == Types.BINARY))
                {
                    hasBinary = true;
                }
            }
        } catch (SQLException sqle)
        {
            successed = false;
            message = sqle.toString();
        }


        String data[] = null;

        try
        {
            while (rs.next())
            {
                recordCount++;
                data = new String[fieldCnt];
                for (int j = 0; j < fieldCnt; j++)
                {
                    if (columnTypeList[j] == Types.BLOB
                            || columnTypeList[j] == Types.LONGVARBINARY
                            || columnTypeList[j] == Types.BINARY
                            || columnTypeList[j] == Types.CLOB)
                    {
                        if (columnTypeList[j] == Types.BLOB)
                        {
                            Blob b = rs.getBlob(j + 1);
                            if (b == null)
                            {
                                binaryBytes = null;
                                colValue = "";
                            } else
                                binaryBytes = b.getBytes(1, (int) b.length());
                        } else if (columnTypeList[j] == Types.CLOB)
                        {

                            Clob c = rs.getClob(j + 1);

                            if (c == null)
                            {
                                colValue = "";
                            } else
                            {
                                Reader inStream = c.getCharacterStream();
                                char[] c2 = new char[(int) c.length()];
                                inStream.read(c2);

                                colValue = String.valueOf(c2);
                                inStream.close();
                                inStream = null;
                            }

                        } else
                        {
                            binaryBytes = rs.getBytes(j + 1);
                        }

                        if (binaryBytes != null
                                && columnTypeList[j] != Types.CLOB)
                            colValue = base64Encoder.encodeToString(binaryBytes);

                    } else if (columnTypeList[j] == Types.DATE)
                    {
                        if (rs.getDate(j + 1) != null)
                            colValue = formatter.format(rs.getDate(j + 1));
                        else
                            colValue = "";
                    } else
                    {
                        colValue = rs.getString(j + 1);
                    }

                    if (colValue == null)
                        colValue = "";

                    data[j] = colValue;
                }

                rowList.add(data);
            }

        } catch (Exception e)
        {
            logger.fatal("buildResultSet error :" + e);
            message = e.toString();
        }

        successed = bResult;
        base64Encoder = null;
        return successed;
    }


    public boolean pushResultSet(ResultSet rs, int rowcount)
    {
        int fieldCnt = 0;
        byte[] binaryBytes = null;
        String colValue = "";
        boolean bResult = false;
        int len = 0;


        Base64.Encoder base64Encoder = Base64.getEncoder();
        java.text.SimpleDateFormat formatter = new java.text.SimpleDateFormat(
                "yyyyMMddHHmmss");


        try
        {
            ResultSetMetaData rsmd = rs.getMetaData();
            fieldCnt = rsmd.getColumnCount();

            ColumnLabelList = new String[fieldCnt];
            columnTypeList = new int[fieldCnt];

            for (int i = 0; i < fieldCnt; i++)
            {
                ColumnLabelList[i] = rsmd.getColumnLabel(i + 1).toUpperCase();
                columnTypeList[i] = rsmd.getColumnType(i + 1);
                fieldList.add(ColumnLabelList[i]);
                if ((columnTypeList[i] == Types.BLOB
                        || columnTypeList[i] == Types.LONGVARBINARY || columnTypeList[i] == Types.BINARY))
                {
                    hasBinary = true;
                }
            }
        } catch (SQLException sqle)
        {
            successed = false;
            message = sqle.toString();
        }


        String data[] = null;

        try
        {
            while (rs.next())
            {
                recordCount++;
                data = new String[fieldCnt];
                for (int j = 0; j < fieldCnt; j++)
                {
                    if (columnTypeList[j] == Types.BLOB
                            || columnTypeList[j] == Types.LONGVARBINARY
                            || columnTypeList[j] == Types.BINARY
                            || columnTypeList[j] == Types.CLOB)
                    {
                        if (columnTypeList[j] == Types.BLOB)
                        {
                            Blob b = rs.getBlob(j + 1);
                            if (b == null)
                            {
                                binaryBytes = null;
                                colValue = "";
                            } else
                                binaryBytes = b.getBytes(1, (int) b.length());
                        } else if (columnTypeList[j] == Types.CLOB)
                        {

                            Clob c = rs.getClob(j + 1);

                            if (c == null)
                            {
                                colValue = "";
                            } else
                            {
                                Reader inStream = c.getCharacterStream();
                                char[] c2 = new char[(int) c.length()];
                                inStream.read(c2);

                                colValue = String.valueOf(c2);
                                inStream.close();
                                inStream = null;
                            }

                        } else
                        {
                            binaryBytes = rs.getBytes(j + 1);
                        }

                        if (binaryBytes != null
                                && columnTypeList[j] != Types.CLOB)
                            colValue = base64Encoder.encodeToString(binaryBytes);

                    } else if (columnTypeList[j] == Types.DATE)
                    {
                        if (rs.getDate(j + 1) != null)
                            colValue = formatter.format(rs.getDate(j + 1));
                        else
                            colValue = "";
                    } else
                    {
                        colValue = rs.getString(j + 1);
                    }

                    if (colValue == null)
                        colValue = "";

                    data[j] = colValue;
                }

                rowList.add(data);
            }

        } catch (Exception e)
        {
            logger.fatal("buildResultSet error :" + e);
            message = e.toString();
        }

        successed = bResult;
        base64Encoder = null;
        return true;
    }



    public void close()
    {
        ColumnLabelList = null;
        fieldList.clear();
        fieldList = null;
        columnTypeList = null;

        rowList.clear();
        rowList = null;


    }





}
