import { Subject, Subscription, from, interval, take } from 'rxjs';
import * as grpc from '@grpc/grpc-js';
import { readFileSync } from 'fs';
import { message_proto } from '../services/protos/server.proto';
import { Status } from '@grpc/grpc-js/build/src/constants';
import assert = require('assert');

const messagesJSON: any = readFileSync('payload.json')
let parsedMessages: any[] = JSON.parse(messagesJSON) // load the fake messages generated for this trial 
let hostServer: string = 'localhost:3000'
let targetServer: string = 'localhost:3000'
let array: any[] = [] // Used for testing    
let intervalToStreamOutGoingMessage: number = 15

/* Checking the values by the end of the test */
interval(5000).subscribe(() => {
    console.log(`All received data: ${array.length}`);
});

async function createServerStreamingServer(): Promise<any> { // '0.0.0.0:3001'
    return new Promise((resolve, reject) => {
        let server = new grpc.Server()
        server.addService(message_proto.MessageService.service, {
            HandleMessage: (call) => { 
                console.log(call.request)
                let response = {
                    id: `1`,
                    message: 'Hi, I received your request. Thanks for choosing FIS enterprise'
                }
                call.write(response)
            }
        })
        server.bindAsync(hostServer, grpc.ServerCredentials.createInsecure(), (err, port) => {
            assert.ifError(err);
            server.start()
            resolve(`gRPC server is running on ${hostServer}`)
        })
    })
}

async function createServerStreamingClient() {
    const client = new message_proto.MessageService(targetServer, grpc.credentials.createInsecure());
    console.log(`Sending request to ${targetServer} to open response channel...`)

    let call = client.HandleMessage({ id: '1', message: `Testing` })

    call.on('status', (status: Status) => {
        if (status == grpc.status.OK) { // only returns a status when there's error. Otherwise it just waits
            console.log(`Message trasmission operation is successful`)
        }
        if (status == grpc.status.UNAVAILABLE) {
            console.log(`Request Failed`)
        }
    });

    call.on('data', (data: any) => {
        console.log(data)
    });

    call.on('error', (err) => {
        console.error(err)
    });

    call.on('end', () => {
        console.log(`DONE`)
    })
}

createServerStreamingServer().then((res) => {
    console.log(res)
    createServerStreamingClient()
})

function queryBooks() {
    // const queryBooksRequest = new QueryBooksRequest();
    // queryBooksRequest.setAuthorPrefix("Geor");
    // const client = grpc.client(BookService.QueryBooks, {
    //   host: host,
    // });
    // client.onHeaders((headers: grpc.Metadata) => {
    //   console.log("queryBooks.onHeaders", headers);
    // });
    // client.onMessage((message: Book) => {
    //   console.log("queryBooks.onMessage", message.toObject());
    // });
    // client.onEnd((code: grpc.Code, msg: string, trailers: grpc.Metadata) => {
    //   console.log("queryBooks.onEnd", code, msg, trailers);
    // });
    // client.start();
    // client.send(queryBooksRequest);
  }