// Copyright 2021 The Pigweed Authors
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.

import {Message} from 'google-protobuf';
import {Status} from 'pigweed/pw_status/ts/status';

import {PendingCalls, Rpc} from './rpc_classes';

export type Callback = (a: any) => any;

/** Represent an in-progress or completed RPC call. */
export class Call {
  private rpcs: PendingCalls;
  private rpc: Rpc;

  private onNext: Callback;
  private onCompleted: Callback;
  private onError: Callback;

  // TODO(jaredweinstein): support async timeout.
  // private timeout: number;
  private status?: Status;
  error?: Status;
  callbackException?: Error;


  constructor(
      rpcs: PendingCalls,
      rpc: Rpc,
      onNext: Callback,
      onCompleted: Callback,
      onError: Callback) {
    this.rpcs = rpcs;
    this.rpc = rpc;

    this.onNext = onNext;
    this.onCompleted = onCompleted;
    this.onError = onError;
  }

  /* Calls the RPC. This must be called immediately after construction. */
  invoke(request?: Message): void {
    const previous = this.rpcs.sendRequest(this.rpc, this, request);

    if (previous !== undefined && !previous.completed()) {
      previous.handleError(Status.CANCELLED)
    }
  }

  private invokeCallback(f: any) {
    try {
      f();
    } catch (err) {
      console.error(
          `An exception was raised while invoking a callback: ${err}`);
      this.callbackException = err
    }
  }

  completed(): boolean {
    return (this.status !== undefined || this.error !== undefined);
  }

  handleResponse(response: Message): void {
    const callback = () => this.onNext(response);
    this.invokeCallback(callback)
  }

  handleCompletion(status: Status) {
    const callback = () => this.onCompleted(status);
    this.invokeCallback(callback)
  }

  cancel(): boolean {
    if (this.completed()) {
      return false;
    }

    this.error = Status.CANCELLED
    return this.rpcs.sendCancel(this.rpc);
  }

  handleError(error: Status): void {
    this.error = error
    const callback = () => this.onError(2);
    this.invokeCallback(callback);
  }
}


/** Tracks the state of a unary RPC call. */
export class UnaryCall extends Call {
  // TODO(jaredweinstein): Complete unary invocation logic.
}

/** Tracks the state of a client streaming RPC call. */
export class ClientStreamingCall extends Call {
  // TODO(jaredweinstein): Complete client streaming invocation logic.
}

/** Tracks the state of a server streaming RPC call. */
export class ServerStreamingCall extends Call {
  // TODO(jaredweinstein): Complete server streaming invocation logic.
}

/** Tracks the state of a bidirectional streaming RPC call. */
export class BidirectionalStreamingCall extends Call {
  // TODO(jaredweinstein): Complete bidirectional streaming invocation logic.
}
