import {
    RpcService,
    Tx, BigNumber,
    ERC20DerivativeService,
    ABI, ExchangeService, DerivativeService,
    DerivativeProviders,
} from './../lib/index';

/**
 * The Example for how to override RpcService sent tx after built.
 */
export class CustomizedRpcService extends RpcService {

    public async afterTxBuilt(caller: string, tx: any): Promise<Tx> {
        return await this.send(tx);
    }

    // override if buildTx send Tx immediately;
    public async buildTx(
        { from, to, data, amount, gasPrice, gasLimit, caller, description, send = true }: {
            from?: string;
            to: string;
            data: any;
            amount?: BigNumber | number;
            gasPrice?: BigNumber | number;
            gasLimit?: BigNumber | number;
            caller?: string;
            description?: string;
            send: boolean
        },
    ): Promise<Tx> {
        if (send) {
            return await super.buildTx({ from, to, data, amount, gasPrice, gasLimit, caller, description });
        } else {
            return await super.createTx({ from, to, data, amount, gasPrice, gasLimit });
        }
    }

    /**
     * your override method reset;
     */
    public async reset() {
        // Your implementation;
    }
}

/**
 * customize your own derivative, you can follow the rules of folder /derivatives/partials
 */
export class CustomizeYourDerivative extends ERC20DerivativeService {

    private exchangeService: ExchangeService;
    public static async create(productAddress: string): Promise<CustomizeYourDerivative> {
        const fakeAbi: any = [];
        const derivative = new DerivativeService(productAddress);
        const exchangeAddress = await derivative.getComponentAddress(DerivativeProviders.EXCHANGE);
        const exchangeService = await ExchangeService.create(exchangeAddress);
        return new CustomizeYourDerivative(productAddress, exchangeService, fakeAbi);
    }

    private constructor(address: string, exchangeService: ExchangeService, abi: ABI) {
        super(address, abi);
        this.exchangeService = exchangeService;
    }

    public async fakeMethod(): Promise<any> {
        // your codes
        return null;
    }
}
