import { Injectable } from '@angular/core';

import { Observable } from 'rxjs';
import { take, map } from 'rxjs/operators';

import { ProtocolService } from '@ucap-webmessenger/protocol';
import {
  SVC_TYPE_OPTION,
  SSVC_TYPE_OPTION_VIEW_REQ,
  SSVC_TYPE_OPTION_UPD_REQ,
  SSVC_TYPE_OPTION_REG_VIEW_REQ,
  SSVC_TYPE_OPTION_REG_UPD_REQ,
  SSVC_TYPE_OPTION_CALL_VIEW_REQ,
  SSVC_TYPE_OPTION_CALL_UPD_REQ
} from '../types/service';
import {
  encodeView,
  decodeView,
  ViewRequest,
  ViewResponse
} from '../protocols/view';
import {
  UpdateRequest,
  UpdateResponse,
  encodeUpdate,
  decodeUpdate
} from '../protocols/update';
import {
  RegViewRequest,
  RegViewResponse,
  encodeRegView,
  decodeRegView
} from '../protocols/reg-view';
import {
  RegUpdateRequest,
  RegUpdateResponse,
  encodeRegUpdate,
  decodeRegUpdate
} from '../protocols/reg-update';
import {
  CallViewRequest,
  CallViewResponse,
  encodeCallView,
  decodeCallView
} from '../protocols/call-view';
import {
  CallUpdateRequest,
  CallUpdateResponse,
  encodeCallUpdate,
  decodeCallUpdate
} from '../protocols/call-update';

@Injectable({
  providedIn: 'root'
})
export class OptionProtocolService {
  constructor(private protocolService: ProtocolService) {}

  public view(req: ViewRequest): Observable<ViewResponse> {
    return this.protocolService
      .call(SVC_TYPE_OPTION, SSVC_TYPE_OPTION_VIEW_REQ, ...encodeView(req))
      .pipe(
        take(1),
        map(res => decodeView(res))
      );
  }

  public update(req: UpdateRequest): Observable<UpdateResponse> {
    return this.protocolService
      .call(SVC_TYPE_OPTION, SSVC_TYPE_OPTION_UPD_REQ, ...encodeUpdate(req))
      .pipe(
        take(1),
        map(res => decodeUpdate(res))
      );
  }

  public regView(req: RegViewRequest): Observable<RegViewResponse> {
    return this.protocolService
      .call(
        SVC_TYPE_OPTION,
        SSVC_TYPE_OPTION_REG_VIEW_REQ,
        ...encodeRegView(req)
      )
      .pipe(
        take(1),
        map(res => decodeRegView(res))
      );
  }

  public regUpdate(req: RegUpdateRequest): Observable<RegUpdateResponse> {
    return this.protocolService
      .call(
        SVC_TYPE_OPTION,
        SSVC_TYPE_OPTION_REG_UPD_REQ,
        ...encodeRegUpdate(req)
      )
      .pipe(
        take(1),
        map(res => decodeRegUpdate(res))
      );
  }

  public callView(req: CallViewRequest): Observable<CallViewResponse> {
    return this.protocolService
      .call(
        SVC_TYPE_OPTION,
        SSVC_TYPE_OPTION_CALL_VIEW_REQ,
        ...encodeCallView(req)
      )
      .pipe(
        take(1),
        map(res => decodeCallView(res))
      );
  }

  public callUpdate(req: CallUpdateRequest): Observable<CallUpdateResponse> {
    return this.protocolService
      .call(
        SVC_TYPE_OPTION,
        SSVC_TYPE_OPTION_CALL_UPD_REQ,
        ...encodeCallUpdate(req)
      )
      .pipe(
        take(1),
        map(res => decodeCallUpdate(res))
      );
  }
}
