package org.iotivity.bridge.homeserver.handler;

import android.content.Context;
import android.util.Log;

import org.iotivity.OCAddDeviceHandler;
import org.iotivity.OCBridge;
import org.iotivity.OCCoreRes;
import org.iotivity.OCDeviceInfo;
import org.iotivity.OCIntrospection;
import org.iotivity.OCMain;
import org.iotivity.OCMainInitHandler;
import org.iotivity.OCUuidUtil;
import org.iotivity.bridge.homeserver.BridgeService;
import org.iotivity.bridge.homeserver.model.Bridge;
import org.iotivity.bridge.homeserver.BridgeServerActivity;
import org.iotivity.bridge.homeserver.utils.Utils;
import org.iotivity.oc.OcPlatform;
import org.iotivity.oc.OcUtils;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

public class BridgeInitHandler implements OCMainInitHandler {

    private static final String TAG = BridgeInitHandler.class.getSimpleName();

    private BridgeService service;
    private OcPlatform ocPlatform;
    private Bridge bridge;

    public BridgeInitHandler(BridgeService service, OcPlatform ocPlatform, Bridge modeldata) {
        this.service = service;
        this.ocPlatform = ocPlatform;
        this.bridge = modeldata ;
    }

    @Override
    public int initialize() {
        Log.d(TAG, "inside BridgeInitHandler.initialize()");
        int ret = ocPlatform.platformInit(Bridge.PLATFORM_MFG_NAME);
        if (ret >= 0) {
            // Create the devices and add them to the platform
            ret = OCBridge.addBridgeDevice(bridge.getName(), "ocf.2.0.5", "ocf.res.1.3.0,ocf.sh.1.3.0");
            /*, new OCAddDeviceHandler() {
                        public void handler() {
                            Log.d(TAG, "inside OcBridge.OCAddDeviceHandler.handler()");
                        }
                    });*/
        } else {
            Log.e(TAG, "Error in platformInit, return value = " + ret);
        }

        OcUtils.setRandomPinHandler(new RandomPinHandler(service));
        return ret;
    }

    @Override
    public void registerResources() {
        Log.d(TAG, "inside BridgeInitHandler.registerResources()");

        byte[] idd_bytes = getFileBytes("idds/bridge_device_IDD.cbor") ; // example : "dummy_bridge_bridge_device_IDD.cbor"
        OCIntrospection.setIntrospectionData(Bridge.BRIDGE_INDEX, idd_bytes);


    }

    @Override
    public void requestEntry() {
        Log.d(TAG, "inside BridgeInitHandler.requestEntry()");

        OCDeviceInfo info = OCCoreRes.getDeviceInfo(Bridge.BRIDGE_INDEX);
        if(info != null) {
            Log.d(TAG, "Bridge DeviceId = " + OCUuidUtil.uuidToString(info.getDi()) + ", Name = " + info.getName());
            bridge.setDeviceId(OCUuidUtil.uuidToString(info.getDi())); ;

            // set immutable device id for Platform Independent Identifier (piid)
            // OCMain.setImmutableDeviceIdentifier(Bridge.BRIDGE_INDEX, info.getDi());
        }
    }

    private byte[] getFileBytes(String filepath) {

        ByteArrayOutputStream baos = null;
        try {
            InputStream is = service.getAssets().open(filepath);
            Log.d(TAG, "reading file " + filepath);

            try {
                byte[] buffer = new byte[8192];
                baos = new ByteArrayOutputStream();
                int length = 0;
                while ((length = is.read(buffer)) != -1) {
                    Log.d(TAG, "bytes read = " + length);
                    baos.write(buffer, 0, length);
                }
            } catch (IOException e) {
                Log.e(TAG, "Error reading file " + filepath);
            } finally {
                try {
                    if (baos != null) {
                        baos.close();
                    }
                } catch (IOException e) {
                    // ignore
                }
                try {
                    if (is != null) {
                        is.close();
                    }
                } catch (IOException e) {
                    // ignore
                }
            }

        } catch (IOException e) {
            Log.e(TAG, "Failed to read " + filepath);
        }

        return ((baos != null) ? baos.toByteArray() : null);
    }
}
