import OrderBook from "../../apiwrapper/orderbook/OrderBook.js";
import OrderBookEntry from "../../apiwrapper/orderbook/OrderBookEntry.js";
import Transaction from "../../apiwrapper/transaction/Transaction.js";
import TransactionSettings from "../../apiwrapper/transaction/TransactionSettings.js";
import AggregatedDataPoint from "../../tradingbot/data/asset/AggregatedDataPoint.js";
import AbstractConverter from "./AbstractConverter.js";
import AggregatedDataPointConverter from "./converters/AggregatedDataPointConverter.js";
import OrderBookConverter from "./converters/OrderBookConverter.js";
import OrderBookEntryConverter from "./converters/OrderBookEntryConverter.js";
import TransactionConverter from "./converters/TransactionConverter.js";
import TransactionSettingsConverter from "./converters/TransactionSettingsConverter.js";

export default class ConverterFactory {
    static OBJECT_TYPE_ORDER_BOOK = 'order_book';
    static OBJECT_TYPE_ORDER_BOOK_ENTRY = 'order_book_entry';
    static OBJECT_TYPE_AGGREGATED_DATA_POINT = 'aggregated_data_point';
    static OBJECT_TYPE_TRANSACTION = 'transaction';
    static OBJECT_TYPE_TRANSACTION_SETTINGS = 'transaction_settings';

    /**
     * @param {any} obj
     * @returns {AbstractConverter}
     */
    static getConverter(obj) {
        if (obj === null) {
            return null;
        }

        if (typeof obj === 'object' && typeof obj._objectType === 'string') {
            return ConverterFactory.#getConverterByTypeString(obj._objectType);
        }

        if (obj instanceof OrderBook) {
            return new OrderBookConverter();
        } else if (obj instanceof OrderBookEntry) {
            return new OrderBookEntryConverter();
        } else if (obj instanceof AggregatedDataPoint){
            return new AggregatedDataPointConverter();
        } else if (obj instanceof Transaction){
            return new TransactionConverter();
        } else if (obj instanceof TransactionSettings){
            return new TransactionSettingsConverter();
        }

        throw new Error("No converter defined for: " + JSON.stringify(obj));
    }

    /**
     * @param {string} obj
     * @returns {AbstractConverter}
     */
    static #getConverterByTypeString(type) {
        switch (type) {
            case this.OBJECT_TYPE_ORDER_BOOK:
                return new OrderBookConverter();
            case this.OBJECT_TYPE_ORDER_BOOK_ENTRY:
                return new OrderBookEntryConverter();
            case this.OBJECT_TYPE_AGGREGATED_DATA_POINT:
                return new AggregatedDataPointConverter();
            case this.OBJECT_TYPE_TRANSACTION:
                return new TransactionConverter();
            case this.OBJECT_TYPE_TRANSACTION_SETTINGS:
                return new TransactionSettingsConverter();
            default:
                throw new Error("No converter defined for type: " + type);
        }
    }
}