import { IContext } from 'pip-services4-components-node';
import { IReferences } from 'pip-services4-components-node';
import { Descriptor } from 'pip-services4-components-node';
import { FilterParams } from 'pip-services4-data-node';
import { PagingParams } from 'pip-services4-data-node';
import { DataPage } from 'pip-services4-data-node';
import { DirectClient } from 'pip-services4-rpc-node';
import { CompositeLogger } from 'pip-services4-observability-node'
import { CompositeCounters } from 'pip-services4-observability-node'

import { IPerfMonClientV1 } from './IPerfMonClientV1';
import { CounterV1 } from './CounterV1';

export class PerfMonDirectClientV1 extends DirectClient<any> implements IPerfMonClientV1 {

    public constructor() {
        super();
        this._dependencyResolver.put('service', new Descriptor("perfmon", "service", "*", "*", "*"))
    }

    public setReferences(references: IReferences) {
        super.setReferences(references);
        this._logger = new CompositeLogger();
        this._counters = new CompositeCounters();
    }

    public async readCounters(context: IContext, filter: FilterParams, paging: PagingParams): Promise<DataPage<CounterV1>> {
        let timing = this.instrument(context, 'counters.read_counters');
        
        try {
            let res = await this._service.readCounters(context, filter, paging);
            timing.endTiming();
            return res;
        } catch (err) {
            timing.endFailure(err);
            throw err;
        }
    }

    public async writeCounter(context: IContext, counter: CounterV1): Promise<CounterV1> {
        let timing = this.instrument(context, 'counters.write_counter');
        
        try {
            let res = await this._service.writeCounter(context, counter);
            timing.endTiming();
            return res;
        } catch (err) {
            timing.endFailure(err);
            throw err;
        }
    }

    public async writeCounters(context: IContext, counters: CounterV1[]): Promise<void> {
        let timing = this.instrument(context, 'counters.write_counters');
        
        try {
            let res = await this._service.writeCounters(context, counters);
            timing.endTiming();
            return res;
        } catch (err) {
            timing.endFailure(err);
            throw err;
        }
    }

    public async clear(context: IContext): Promise<void> {
        let timing = this.instrument(context, 'counters.clear');
        
        try {
            let res = await this._service.clear(context);
            timing.endTiming();
            return res;
        } catch (err) {
            timing.endFailure(err);
            throw err;
        }
    }

}