var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
import { QueueComProtocol } from '@iotize/tap/protocol/core';
import { of, Subject } from 'rxjs';
import { delay, first } from 'rxjs/operators';
import { debug } from '../debug';
import { MockRouter } from './mock-router';
const TAG = 'MockProtocol';
export function createMockProtocol() {
    return new MockProtocol();
}
/**
 *
 * <p>
 * This is a mock com protocol for testing only
 * <p>
 * We can simulate iotize response according to the request message
 */
export class MockProtocol extends QueueComProtocol {
    constructor() {
        super();
        this.mockOptions = {
            connect: {
                delay: 100,
            },
            disconnect: {
                delay: 100,
            },
            write: {
                delay: 1,
            },
        };
        this.input = new Subject();
        this.output = new Subject();
        this._router = new MockRouter();
        // this.connectDelay = 2000;
        // this.disconnectDelay = 2000;
        // this.callback = callback;
        // this.lastReceivedData = new Uint8Array(0);
        // this.configuration = new Configuration();
        // this.configuration.connectionTimeoutMillis = 3000;
        // this.configuration.sendTimeoutMillis = 3000;
    }
    static MIRROR() {
        const mockProtocol = new MockProtocol();
        mockProtocol.input.subscribe((input) => {
            mockProtocol.setOutputData(input);
        });
        // mockProtocol.router.addRoute(
        //     (command: Uint8Array) => {
        //         return true;
        //     },
        //     (request: Uint8Array) => {
        //         return request;
        //     }
        // );
        return mockProtocol;
    }
    // /**
    //  * Create a new instance from roote mapping
    //  */
    // public static createFromRoutes(map: RouteMapping): MockProtocol {
    //     const mockProtocol = new MockProtocol();
    //     mockProtocol.router.addRoutes(map);
    //     return mockProtocol;
    // }
    // public get router(): MockRouter {
    //     return this._router;
    // }
    setConnectionState(connectionState) {
        debug(TAG, `setConnectionState: ${connectionState}`);
        this.connectionState = connectionState;
        return this;
    }
    setConnectDelay(connectDelay) {
        this.mockOptions.connect.delay = connectDelay;
        return this;
    }
    getDisconnectDelay() {
        return this.mockOptions.disconnect.delay;
    }
    setDisconnectDelay(disconnectDelay) {
        this.mockOptions.disconnect.delay = disconnectDelay;
        return this;
    }
    setOutputData(inputData) {
        this.lastTranseiveData = inputData;
        this.output.next(inputData);
    }
    setInputData(outputData) {
        this.lastReceivedData = outputData;
        this.input.next(outputData);
    }
    setCallback(callback) {
        this.callback = callback;
    }
    _connect(options) {
        return of(undefined).pipe(delay(this.mockOptions.connect.delay));
    }
    _disconnect(options) {
        return of(undefined).pipe(delay(this.mockOptions.disconnect.delay));
    }
    write(request) {
        return __awaiter(this, void 0, void 0, function* () {
            try {
                if (this.callback) {
                    yield this.callback.beforeWrite(request);
                }
                // this.lastReceivedData = request;
                // const response = this.router.findRoute(request);
                // if (!response) {
                //     throw new Error(`Not route for request ${bufferToHexString(request)}`)
                // }
                // debug(
                //     TAG,
                //     'MockProtocol',
                //     'Mocking response for ' + request + ' => ' + response
                // );
                // var result = this.responseEncoder.encode(response);
                this.setInputData(request);
                if (this.callback) {
                    yield this.callback.afterWrite(request);
                }
                return new Promise((resolve) => setTimeout(resolve, this.mockOptions.write.delay));
            }
            catch (err) {
                return new Promise((resolve, reject) => setTimeout(() => reject(err), this.mockOptions.write.delay));
            }
        });
    }
    read() {
        try {
            if (this.callback) {
                this.callback.beforeRead();
            }
            return this.output
                .pipe(first())
                .toPromise()
                .then((v) => (v ? v : new Uint8Array()));
            // while (!this.hasNewData()) {
            //     // TODO wait ??
            // }
            // if (this.lastTranseiveData) {
            //     const result = of(this.lastTranseiveData);
            //     if (this.callback) {
            //         this.callback.afterRead(result);
            //     }
            //     return result.toPromise();
            // } else {
            //     return Promise.reject(new Error('Read timeout'));
            // }
        }
        catch (err) {
            return Promise.reject(err);
        }
    }
}
//    public addOnRequestListener() {
//        this.mOnRequestListener =
//    }
//    public interface onRequestListener{
//        onRequest(RequestMessage request);
//    }
//# sourceMappingURL=data:application/json;base64, 