// 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 {ProtoCollection} from '@pigweed/pw_protobuf_compiler';
import {
  MethodDescriptorProto,
  ServiceDescriptorProto,
} from 'google-protobuf/google/protobuf/descriptor_pb';

import {hash} from './hash';

interface ChannelOutput {
  (data: Uint8Array): void;
}

export class Channel {
  readonly id: number;
  private output: ChannelOutput;

  constructor(id: number, output: ChannelOutput = () => {}) {
    this.id = id;
    this.output = output;
  }

  send(data: Uint8Array) {
    this.output(data);
  }
}

/** Describes an RPC service. */
export class Service {
  readonly name: string;
  readonly id: number;
  readonly methods = new Map<number, Method>();
  readonly methodsByName = new Map<string, Method>();

  constructor(
    descriptor: ServiceDescriptorProto,
    protoCollection: ProtoCollection,
    packageName: string
  ) {
    this.name = packageName + '.' + descriptor.getName()!;
    this.id = hash(this.name);
    descriptor
      .getMethodList()
      .forEach((methodDescriptor: MethodDescriptorProto) => {
        const method = new Method(methodDescriptor, protoCollection, this);
        this.methods.set(method.id, method);
        this.methodsByName.set(method.name, method);
      });
  }
}

export enum MethodType {
  UNARY,
  SERVER_STREAMING,
  CLIENT_STREAMING,
  BIDIRECTIONAL_STREAMING,
}

/** Describes an RPC method. */
export class Method {
  readonly service: Service;
  readonly name: string;
  readonly id: number;
  readonly clientStreaming: boolean;
  readonly serverStreaming: boolean;
  readonly requestType: any;
  readonly responseType: any;

  constructor(
    descriptor: MethodDescriptorProto,
    protoCollection: ProtoCollection,
    service: Service
  ) {
    this.name = descriptor.getName()!;
    this.id = hash(this.name);
    this.service = service;
    this.serverStreaming = descriptor.getServerStreaming()!;
    this.clientStreaming = descriptor.getClientStreaming()!;

    const requestTypePath = descriptor.getInputType()!;
    const responseTypePath = descriptor.getOutputType()!;

    // Remove leading period if it exists.
    this.requestType = protoCollection.getMessageCreator(
      requestTypePath.replace(/^\./, '')
    )!;
    this.responseType = protoCollection.getMessageCreator(
      responseTypePath.replace(/^\./, '')
    )!;
  }

  get type(): MethodType {
    if (this.clientStreaming && this.serverStreaming) {
      return MethodType.BIDIRECTIONAL_STREAMING;
    } else if (this.clientStreaming && !this.serverStreaming) {
      return MethodType.CLIENT_STREAMING;
    } else if (!this.clientStreaming && this.serverStreaming) {
      return MethodType.SERVER_STREAMING;
    } else if (!this.clientStreaming && !this.serverStreaming) {
      return MethodType.UNARY;
    }
    throw Error('Unhandled streaming condition');
  }
}
