package kr.co.icontrols.iotplatform.Database;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.provider.BaseColumns;

import java.util.ArrayList;

import kr.co.icontrols.iotplatform.DataClass.DeviceInfo;

import static kr.co.icontrols.iotplatform.Database.DatabaseHelper.COLUMN_GROUP_ID;
import static kr.co.icontrols.iotplatform.Database.DatabaseHelper.COLUMN_GROUP_NAME;
import static kr.co.icontrols.iotplatform.Database.DatabaseHelper.COLUMN_GROUP_RANK;
import static kr.co.icontrols.iotplatform.Database.DatabaseHelper.COLUMN_ID;
import static kr.co.icontrols.iotplatform.Database.DatabaseHelper.COLUMN_NAME;
import static kr.co.icontrols.iotplatform.Database.DatabaseHelper.COLUMN_OWNER_ID;
import static kr.co.icontrols.iotplatform.Database.DatabaseHelper.COLUMN_RANK;
import static kr.co.icontrols.iotplatform.Database.DatabaseHelper.COLUMN_SHARED_NAME;
import static kr.co.icontrols.iotplatform.Database.DatabaseHelper.COLUMN_TYPE;

/**
 * DB 관리 Class
 */
public class DBUtil {
    public static final String TAG = DBUtil.class.getSimpleName();

    private static DBUtil sInstance = null;

    private static Context mContext;

    private static String[] mColumns = new String[] {
            BaseColumns._ID,
            COLUMN_ID,
            COLUMN_NAME,
            COLUMN_GROUP_ID,
            COLUMN_GROUP_NAME,
            COLUMN_SHARED_NAME,
            COLUMN_OWNER_ID,
            COLUMN_TYPE,
            COLUMN_RANK,
            COLUMN_GROUP_RANK,
    };

    private DBUtil(Context context) {
        mContext = context;
    }

    public static void init(Context context) {
        if (sInstance == null) {
            sInstance = new DBUtil(context);
        }
    }

    /**
     * DB의 정보를 DeviceInfo class에 맞게 변경.
     * @param c
     * @return
     */
    private static DeviceInfo cursorToDeviceInfo(Cursor c) {
        DeviceInfo deviceInfo = new DeviceInfo();
        deviceInfo.deviceId = c.getString(1);
        deviceInfo.friendlyName = c.getString(2);
        deviceInfo.dgroupId = c.getString(3);
        deviceInfo.dgroupName = c.getString(4);
        deviceInfo.sharedFriendlyName = c.getString(5);
        deviceInfo.ownerId = c.getString(6);
        deviceInfo.deviceType = c.getString(7);
        deviceInfo.rank = c.getInt(8);
        deviceInfo.groupRank = c.getInt(9);
        return deviceInfo;
    }

    /**
     * DEVICE ID 값을 이용한 디바이스 정보 획득.
     * @param tableName DB 테이블 이름
     * @param deviceId 디바이스 ID
     */
    synchronized public static DeviceInfo getDeviceInfoForId(String tableName ,String deviceId) {
        SQLiteDatabase db = DatabaseHelper.getInstance().getReadableDatabase();

        DeviceInfo deviceInfo = null;
        String [] selectionArg = new String [] { deviceId };

        Cursor c = db.query(tableName, mColumns, COLUMN_ID+" == ?", selectionArg, null, null, null);

        if (c != null) {
            if (c.getCount() > 0) {
                c.moveToFirst();
                deviceInfo = cursorToDeviceInfo(c);
            }
            c.close();
        }
        db.close();
        return deviceInfo;
    }

    /**
     * GROUP ID 값을 이용한 디바이스 정보 획득.
     * @param tableName DB 테이블 이름
     * @param groupId 그룹 ID
     */
    synchronized public static  ArrayList<DeviceInfo> getDeviceInfoForGroupId(String tableName ,String groupId) {
        SQLiteDatabase db = DatabaseHelper.getInstance().getReadableDatabase();
        ArrayList<DeviceInfo> deviceInfos = new ArrayList<>();
        String [] selectionArg = new String [] { groupId };
        Cursor c = db.query(tableName, mColumns, COLUMN_GROUP_ID+" == ?", selectionArg, null, null, null);
        if (c.moveToFirst()) {
            do {
                deviceInfos.add(cursorToDeviceInfo(c));
            } while (c.moveToNext());
        }
        c.close();
        return deviceInfos;
    }



    /**
     * DB의 모든 디바이스 정보 획득.
     * @param tableName DB 테이블 이름
     * @return
     */
    synchronized public static ArrayList<DeviceInfo> getAllDeviceInfos(String tableName) {

        SQLiteDatabase db = DatabaseHelper.getInstance().getReadableDatabase();
        ArrayList<DeviceInfo> deviceInfos = new ArrayList<>();

        Cursor c = db.query(tableName, mColumns, null, null, null, null, COLUMN_RANK + " ASC, " + BaseColumns._ID + " DESC");
        if (c.moveToFirst()) {
            do {
                deviceInfos.add(cursorToDeviceInfo(c));
            } while (c.moveToNext());
        }
        c.close();
        return deviceInfos;
    }

    /**
     * DB의 모든 디바이스 정보 획득.
     * @param tableName DB 테이블 이름
     * @return
     */
    synchronized public static void getAllDeviceInfos(String tableName, ArrayList<DeviceInfo> deviceInfos) {
        SQLiteDatabase db = DatabaseHelper.getInstance().getReadableDatabase();
        Cursor c = db.query(tableName, mColumns, null, null, null, null, COLUMN_RANK + " ASC, " + BaseColumns._ID + " DESC");
        if (c.moveToFirst()) {
            do {
                deviceInfos.add(cursorToDeviceInfo(c));
            } while (c.moveToNext());
        }
        c.close();
    }

    /**
     * DB에 디바이스 정보 추가.
     * @param tableName DB 테이블 이름
     * @param deviceInfo 디바이스 정보 Class
     * @return
     */
    synchronized public static long putDeviceInfo(String tableName, DeviceInfo deviceInfo) {
        SQLiteDatabase db = DatabaseHelper.getInstance().getWritableDatabase();
        long _id = -1;
        ContentValues cv = new ContentValues();
        cv.put(COLUMN_ID, deviceInfo.deviceId);
        cv.put(COLUMN_TYPE, deviceInfo.deviceType);
        cv.put(COLUMN_GROUP_ID, deviceInfo.dgroupId);
        cv.put(COLUMN_GROUP_NAME, deviceInfo.dgroupName);
        cv.put(COLUMN_NAME, deviceInfo.friendlyName);
        cv.put(COLUMN_OWNER_ID, deviceInfo.ownerId);
        cv.put(COLUMN_RANK, deviceInfo.rank);
        cv.put(COLUMN_GROUP_RANK, deviceInfo.groupRank);
        cv.put(COLUMN_SHARED_NAME, deviceInfo.sharedFriendlyName);
        _id = db.insert(tableName, null, cv);
        db.close();
        return _id;
    }

    /**
     * 해당 상품 정보를 DB 업데이트
     * @param deviceInfo
     */
    synchronized public static void updateDeviceItem(String tableName, DeviceInfo deviceInfo) {
        SQLiteDatabase db = DatabaseHelper.getInstance().getWritableDatabase();
        String [] selectionArg = new String [] { deviceInfo.deviceId };

        ContentValues cv = new ContentValues();
        cv.put(COLUMN_ID, deviceInfo.deviceId);
        cv.put(COLUMN_TYPE, deviceInfo.deviceType);
        cv.put(COLUMN_GROUP_ID, deviceInfo.dgroupId);
        cv.put(COLUMN_GROUP_NAME, deviceInfo.dgroupName);
        cv.put(COLUMN_NAME, deviceInfo.friendlyName);
        cv.put(COLUMN_OWNER_ID, deviceInfo.ownerId);
        cv.put(COLUMN_RANK, deviceInfo.rank);
        cv.put(COLUMN_GROUP_RANK, deviceInfo.groupRank);
        cv.put(COLUMN_SHARED_NAME, deviceInfo.sharedFriendlyName);
        db.update(tableName, cv, COLUMN_ID+" == ?", selectionArg);
        db.close();
    }

    /**
     * DB에서 특정 디바이스 정보 삭제.
     * @param tableName DB 테이블 이름
     * @param deviceInfo 디바이스 정보 Class
     */
    synchronized public static void removeDeviceInfo(String tableName, DeviceInfo deviceInfo) {
        String [] selectionArg = new String [] { deviceInfo.deviceId };
        SQLiteDatabase db = DatabaseHelper.getInstance().getWritableDatabase();
        db.delete(tableName, COLUMN_ID+" == ?", selectionArg);
        db.close();
    }

    /**
     *  DB의 특정 Table의 모든 데이터 삭제.
     */
    synchronized public static void removeAllDeviceInfos(String tableName) {
        SQLiteDatabase db = DatabaseHelper.getInstance().getWritableDatabase();
        db.delete(tableName, null, null);
        db.close();
    }

    synchronized public static void removeDeviceInfoAtAllTable(String deviceId) {
        String [] selectionArg = new String [] { deviceId };
        SQLiteDatabase db = DatabaseHelper.getInstance().getWritableDatabase();
        db.delete(DatabaseHelper.TABLE_SMART_LIGHT, COLUMN_ID+" == ?", selectionArg);
        db.delete(DatabaseHelper.TABLE_DEVICE_HOME, COLUMN_ID+" == ?", selectionArg);
        db.delete(DatabaseHelper.TABLE_DEVICE_RANK, COLUMN_ID+" == ?", selectionArg);
        db.close();
    }


    /**
     *  DB의 모든 데이터 삭제.
     */
    synchronized public static void removeAll() {
        SQLiteDatabase db = DatabaseHelper.getInstance().getWritableDatabase();
        db.delete(DatabaseHelper.TABLE_SMART_LIGHT, null, null);
        db.delete(DatabaseHelper.TABLE_DEVICE_HOME, null, null);
        db.delete(DatabaseHelper.TABLE_DEVICE_RANK, null, null);
        db.close();
    }
}
