import express from "express";
import bodyParser from "body-parser";
import cors from "cors";
import WebViewDataProvider from "./WebViewDataProvider.js";
import ConverterFactory from "./converter/ConverterFactory.js";

export default class RestClient {

    /**
     * @type {express}
     */
    #service = null;

    /**
     * @type {WebViewDataProvider}
     */
    #dataProvider = null;

    /**
     * @type {number}
     */
    #port = 3333;

    /**
     * @param {number} port 
     */
    constructor(port = 3333){
        this.#port = port;

        this.#service = express();
        this.#service.use(bodyParser.json({ limit: '80mb' }));
        this.#service.use(cors({ origin: '*' }));

        this.#registerEndpoints();
    }

    /**
     * @param {number} port 
     */
    setPort(port){
        this.#port = port;
    }

    /**
     * @param {WebViewDataProvider} dataProvider 
     */
    start(dataProvider){
        this.#dataProvider = dataProvider;
        this.#service.listen(this.#port, () => { });
    }

    #registerEndpoints() {
        this.#registerGetters();
        this.#registerSetters();
    }

    #registerGetters(){
        this.#service.get("/assets/orderbook", (req, res, next) => {
            res.json(this.#getAllOrderBooks());
        });

        this.#service.get("/asset/:symbol/orderbook", (req, res, next) => {
            res.json(this.#getAssetOrderBook(req.params.symbol));
        });

        this.#service.get("/worker/:name/attribute/:attr", (req, res, next) => {
            res.json(this.#getWorkerAttribute(req.params.name, req.params.attr));
        });

        /*this.#service.get("/transactions", (req, res, next) => {
            res.json(this.#getAssetOrderBook(req.params.symbol));
        });*/
    }

    #registerSetters(){

    }

    #getAssetOrderBook(asset){
        const orderBook = this.#dataProvider.getOrderBook(asset);

        return ConverterFactory.getConverter(orderBook).toRestObject(orderBook);
    }

    #getAllOrderBooks(){
        const orderBooks = [];

        this.#dataProvider.getAvailableAssets().forEach(asset => {
            const orderBook = this.#dataProvider.getOrderBook(asset);
            orderBooks.push(ConverterFactory.getConverter(orderBook).toRestObject(orderBook));
        });

        return orderBooks;
    }

    #getWorkerAttribute(name, attributeName){
        let result = null;
        this.#dataProvider.getWorkers().forEach(w => {
            if(w.getName() === name){
                result =  w.getAttribute(attributeName);
            }
        });

        return result;
    }
}