package org.wikiwebserver.util;

import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.rpc.Service;

import org.apache.axis.client.ServiceFactory;

import com.betfair.www.publicapi.types.exchange.v3.APIRequestHeader;
import com.betfair.www.publicapi.types.exchange.v3.GetAccountFundsReq;
import com.betfair.www.publicapi.types.exchange.v3.GetAccountFundsResp;
import com.betfair.www.publicapi.types.exchange.v3.GetMarketErrorEnum;
import com.betfair.www.publicapi.types.exchange.v3.GetMarketPricesErrorEnum;
import com.betfair.www.publicapi.types.exchange.v3.GetMarketPricesReq;
import com.betfair.www.publicapi.types.exchange.v3.GetMarketPricesResp;
import com.betfair.www.publicapi.types.exchange.v3.GetMarketReq;
import com.betfair.www.publicapi.types.exchange.v3.GetMarketResp;
import com.betfair.www.publicapi.types.exchange.v3.Market;
import com.betfair.www.publicapi.types.exchange.v3.MarketPrices;
import com.betfair.www.publicapi.types.global.v3.APIErrorEnum;
import com.betfair.www.publicapi.types.global.v3.LoginErrorEnum;
import com.betfair.www.publicapi.types.global.v3.LoginReq;
import com.betfair.www.publicapi.types.global.v3.LoginResp;
import com.betfair.www.publicapi.v3.BFExchangeService.BFExchangeService_BindingStub;
import com.betfair.www.publicapi.v3.BFGlobalService.BFGlobalService_BindingStub;

public class BetFairHelper {
    
    private static String endPointGlobal = "https://api.betfair.com/global/v3/BFGlobalService";
    private static String endPointUK = "https://api.betfair.com/exchange/v3/BFExchangeService";    
    
    private String username;
    private String password;
    private String sessionToken;    
    
    private static int productID = 82; // Free API  
    
    public BetFairHelper(String username, String password) {
        this.username = username;
        this.password = password;
    }
    
    /**
     * Login to BetFair
     * @throws Exception if there is a problem
     */
    public String login() throws Exception {

        Service service = ServiceFactory.newInstance().createService(new QName("login"));
        BFGlobalService_BindingStub stub = new BFGlobalService_BindingStub(new URL(endPointGlobal), service);

        LoginReq req = new LoginReq();
        req.setUsername(username);
        req.setPassword(password);
        req.setProductId(productID);

        LoginResp resp = stub.login(req);

        if (resp.getErrorCode() == LoginErrorEnum.API_ERROR || 
            resp.getHeader().getErrorCode() != APIErrorEnum.OK) {
            
            return resp.getHeader().getErrorCode().toString();
            
        } else if (resp.getErrorCode() != LoginErrorEnum.OK) {
            return resp.getErrorCode().toString();
        } else {
            this.sessionToken = resp.getHeader().getSessionToken();
            return "Logged in";
        }

    }   
    
    /**
     * Test method to get Account Funds
     * @param exchangeId UK or AUS exchange to use
     * @throws Exception if there is a problem
     */
    public GetAccountFundsResp getAcctFunds() throws Exception {

        //Set up service calls
        String sServiceName = "getAccountFunds";
        Service service = ServiceFactory.newInstance().createService(new QName(sServiceName));
        BFExchangeService_BindingStub stubUK = new BFExchangeService_BindingStub(new URL(endPointUK), service);

        //Initialise request object
        GetAccountFundsReq req = new GetAccountFundsReq();

        APIRequestHeader hdr = new APIRequestHeader();
        hdr.setClientStamp(System.currentTimeMillis());
        hdr.setSessionToken(this.sessionToken);    
        req.setHeader(hdr);

        //Make the call
        GetAccountFundsResp resp = stubUK.getAccountFunds(req);

        this.sessionToken = resp.getHeader().getSessionToken();
        
        if (resp.getHeader().getErrorCode() != com.betfair.www.publicapi.types.exchange.v3.APIErrorEnum.OK) {
            throw new Exception(resp.getHeader().getErrorCode().toString());
        }
        else return resp;
    }    
    
    /**
     * Test method to get the Market information
     * @param marketId Market to retrieve
     * @param exchangeId Exchange where the market is located
     * @throws Exception if there is a problem
     */
    public Market getMarket(int marketId) throws Exception {

        //Set up service calls
        Service service = ServiceFactory.newInstance().createService(new QName("getMarket"));
        BFExchangeService_BindingStub stubUK = new BFExchangeService_BindingStub(new URL(endPointUK), service);

        //Initialise the request object
        GetMarketReq req = new GetMarketReq();
        req.setMarketId(marketId);
        
        APIRequestHeader hdr = new APIRequestHeader();
        hdr.setClientStamp(System.currentTimeMillis());
        hdr.setSessionToken(this.sessionToken);    
        req.setHeader(hdr);
        
        //Make the call
        GetMarketResp resp = null;
        resp = stubUK.getMarket(req);
        
        this.sessionToken = resp.getHeader().getSessionToken();
        
        if (resp.getErrorCode() == GetMarketErrorEnum.API_ERROR) {
            throw new Exception(resp.getHeader().getErrorCode().toString());
        }
        else if (resp.getErrorCode() != GetMarketErrorEnum.OK) {
            throw new Exception(resp.getErrorCode().toString());
        } 
        else return resp.getMarket();
    }    
 
    /**
     * Test method to get the Market information
     * @param marketId Market to retrieve
     * @param exchangeId Exchange where the market is located
     * @throws Exception if there is a problem
     */
    public MarketPrices getMarketPrices(int marketId) throws Exception {

        //Set up service calls
        Service service = ServiceFactory.newInstance().createService(new QName("getMarketPrices"));
        BFExchangeService_BindingStub stubUK = new BFExchangeService_BindingStub(new URL(endPointUK), service);

        //Initialise the request object
        GetMarketPricesReq req = new GetMarketPricesReq();
        req.setMarketId(marketId);
        
        APIRequestHeader hdr = new APIRequestHeader();
        hdr.setClientStamp(System.currentTimeMillis());
        hdr.setSessionToken(this.sessionToken);    
        req.setHeader(hdr);
        
        //Make the call
        GetMarketPricesResp resp = null;
        resp = stubUK.getMarketPrices(req);
        
        this.sessionToken = resp.getHeader().getSessionToken();
        
        if (resp.getErrorCode() == GetMarketPricesErrorEnum.API_ERROR) {
            throw new Exception(resp.getHeader().getErrorCode().toString());
        }
        else if (resp.getErrorCode() != GetMarketPricesErrorEnum.OK) {
            throw new Exception(resp.getErrorCode().toString());
        } 
        else return resp.getMarketPrices();
    }    
}

