
import {Log} from "fme-logger";
var L = new Log("onada-quotes");
L.setLevel("debug");
import {OandaQuote,OandaInstrument} from "../models/oanda-quotes";
import  * as OandaAdapter from  "oanda-adapter";
import {FmeQuoteRt,FmeSymbol } from "fme-quotes-models";
import * as _m from "moment-timezone";

export class OandaController {
    subscribers: any[] = [];
    client:any;
    instruments:OandaInstrument[] = [];
    streamStarted = false;
    availableSymbols:FmeSymbol[] = [];

    constructor(private environment:string, private accessToken:string, private username:string, private accountId:string) {
        
    }

    addSymbol = (symbol:string) => {
      //  this.client.subscribePrice(this.accountId,symbol,this.streamOut);
    }

    connect = () => {
        L.info("connect");
        this.client = new OandaAdapter ( {
            environment:this.environment,
            accessToken:this.accessToken,
            username: this.username
        });

    }

    convertSymbol = (symbolIn:string) => {
        var symbol =  this.availableSymbols.find( (a) => {return a.vendorSymbol === symbolIn})
        if (symbol) {
            return symbol.symbol;
        }
        L.error("convertSymbol",symbolIn,this.availableSymbols);
        return "N/F";
    }
    
    convertSymbol2FmeSymbol = (symbolIn:OandaInstrument) => {
        var symbolOut = new FmeSymbol();
        symbolOut.symbol  = symbolIn.displayName.replace("_","-");
        symbolOut.name = symbolIn.instrument;
        symbolOut.decimalPoints = this.numberOfDecimals(symbolIn.pip);
        symbolOut.id = symbolIn.instrument;
        symbolOut.intervals = [];
        symbolOut.isStreaming = true;
        symbolOut.source = "gdax";
        symbolOut.vendorSymbol = symbolIn.instrument;
        return symbolOut;
    }

    convertTicker = (quote:OandaQuote) => {
        var fmeQuoteRt = new FmeQuoteRt();
        fmeQuoteRt.symbol = quote.instrument.replace("_","-");
        fmeQuoteRt.bid = quote.bid;
        fmeQuoteRt.ask = quote.ask;
        fmeQuoteRt.last = quote.ask;
        fmeQuoteRt.timestamp = _m(quote.time).toDate();
        fmeQuoteRt.source = "OANDA";
        fmeQuoteRt.decimalPoints = this.getDecimalPoints(quote.instrument);
        return fmeQuoteRt;
    }


    delay = async (seconds:number) => {
        setTimeout( async () => {
            return true;
        },seconds*1000)
    }
    
    
    
    getDecimalPoints = (instrument:string) => {
        var dp = this.availableSymbols.find( (a) => {return a.vendorSymbol == instrument});
        if (dp) return dp.decimalPoints;
        else return 2;
    }

    getSymbols = async () => {
        L.debug("Processing getSymbols");
        return new Promise ( async ( resolve,reject ) => {
            try{
                L.debug("Trying getInstruments",this.client)
                this.client.getInstruments(this.accountId, (error:any,data:any) => {
                    this.instruments = data;
                    for (var i in this.instruments) {
                        var symbol = this.instruments[i];
                        this.availableSymbols.push(this.convertSymbol2FmeSymbol(symbol));
                    }
                    resolve(this.instruments.length);
                    this.startStream(null);
                })
            } catch (err) {
                L.error("getSymbols",err)
                reject(err)
                return
            }
        }) 
    }

    private numberOfDecimals (number:string) {
        var index = number.indexOf(".");
        if (index == -1) return 0
        return number.length - index - 1;
    }


    setDecimalPoints = () => {
        for (var i in this.instruments) {
            var instrument = this.instruments[i];
            instrument.decimalPoints = this.numberOfDecimals(instrument.pip);
        }
    }

    subscribe = ( clientName:string,clientFunction:any ) => {
        var idx = this.subscribers.findIndex( (a) => {return a.name == clientName});
        if (idx == -1) {
            L.debug("New subscriber",clientName);
            this.subscribers.push({name:clientName,callBack:clientFunction});
        } else {
            L.debug("Updating subscriber",clientName);
            this.subscribers[idx] = {name:clientName,callBack:clientFunction};
        }
    }

    streamOut = (data:OandaQuote) => {
        var q = this.convertTicker(data);
        for (var i in this.subscribers) {
            this.subscribers[i].callBack(q);
        }
    }

    
    startStream = async (symbols:any) => {
        if (this.streamStarted) return;
        this.streamStarted = true;
        for (var i in this.instruments) {
            this.client.subscribePrice(this.accountId, this.instruments[i].instrument, this.streamOut );
        }
       
    }

    stopStream = () => {

    }

    unSubscribe = (clientName:string) => {
        var idx = this.subscribers.findIndex( (a) => {return a.name == clientName});
        if (idx == -1) {
            L.error("Unsubscribe - Client does not exist",clientName);
        } else {
            this.subscribers.slice(idx,1);
        } 
    }




}
       