// Copyright 2023 Google LLC.  All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd

use conformance_rust_proto::{ConformanceRequest, ConformanceResponse, WireFormat};

#[cfg(cpp_kernel)]
use protobuf_cpp as protobuf;

#[cfg(upb_kernel)]
use protobuf_upb as protobuf;

use protobuf::prelude::*;
use protobuf::Optional::{Set, Unset};
use protobuf::ParseError;

use std::io::{self, ErrorKind, Read, Write};
use test_messages_edition2023_rust_proto::TestAllTypesEdition2023;
use test_messages_proto2_editions_rust_proto::TestAllTypesProto2 as EditionsTestAllTypesProto2;
use test_messages_proto2_rust_proto::TestAllTypesProto2;
use test_messages_proto3_editions_rust_proto::TestAllTypesProto3 as EditionsTestAllTypesProto3;
use test_messages_proto3_rust_proto::TestAllTypesProto3;

/// Returns Some(i32) if a binary read can succeed from stdin.
/// Returns None if we have reached an EOF.
/// Panics for any other error reading.
fn read_little_endian_i32_from_stdin() -> Option<i32> {
    let mut buffer = [0_u8; 4];
    if let Err(e) = io::stdin().read_exact(&mut buffer) {
        match e.kind() {
            ErrorKind::UnexpectedEof => None,
            _ => panic!("failed to read i32 from stdin"),
        }
    } else {
        Some(i32::from_le_bytes(buffer))
    }
}

/// Returns Some of a conformance request read from stdin.
/// Returns None if we have hit an EOF that suggests the test suite is complete.
/// Panics in any other case (e.g. an EOF in a place that would imply a
/// programmer error in the conformance test suite).
fn read_request_from_stdin() -> Option<ConformanceRequest> {
    let msg_len = read_little_endian_i32_from_stdin()?;
    let mut serialized = vec![0_u8; msg_len as usize];
    io::stdin().read_exact(&mut serialized).unwrap();
    Some(ConformanceRequest::parse(&serialized).unwrap())
}

fn write_response_to_stdout(resp: &ConformanceResponse) {
    let bytes = resp.serialize().unwrap();
    let len = bytes.len() as u32;
    let mut handle = io::stdout();
    handle.write_all(&len.to_le_bytes()).unwrap();
    handle.write(&bytes).unwrap();
    handle.flush().unwrap();
}

fn do_test(req: &ConformanceRequest) -> ConformanceResponse {
    let mut resp = ConformanceResponse::new();
    let message_type = req.message_type();

    if req.requested_output_format() != WireFormat::Protobuf {
        resp.set_skipped("only wire format output implemented");
        return resp;
    }

    let bytes = match req.protobuf_payload_opt() {
        Unset(_) => {
            resp.set_skipped("only wire format input implemented");
            return resp;
        }
        Set(bytes) => bytes,
    };

    fn roundtrip<T: Message>(bytes: &[u8]) -> Result<Vec<u8>, ParseError> {
        T::parse(bytes).map(|msg| msg.serialize().unwrap())
    }

    let serialized = match message_type.as_bytes() {
        b"protobuf_test_messages.proto2.TestAllTypesProto2" => {
            roundtrip::<TestAllTypesProto2>(bytes)
        }
        b"protobuf_test_messages.proto3.TestAllTypesProto3" => {
            roundtrip::<TestAllTypesProto3>(bytes)
        }
        b"protobuf_test_messages.editions.TestAllTypesEdition2023" => {
            roundtrip::<TestAllTypesEdition2023>(bytes)
        }
        b"protobuf_test_messages.editions.proto2.TestAllTypesProto2" => {
            roundtrip::<EditionsTestAllTypesProto2>(bytes)
        }
        b"protobuf_test_messages.editions.proto3.TestAllTypesProto3" => {
            roundtrip::<EditionsTestAllTypesProto3>(bytes)
        }
        _ => panic!("unexpected msg type {message_type}"),
    };

    match serialized {
        Ok(serialized) => {
            resp.set_protobuf_payload(serialized);
        }
        Err(_) => {
            resp.set_parse_error("failed to parse bytes");
        }
    }

    resp
}

fn main() {
    let mut total_runs = 0;
    while let Some(req) = read_request_from_stdin() {
        let resp = do_test(&req);
        write_response_to_stdout(&resp);
        total_runs += 1;
    }
    eprintln!("conformance_rust: received EOF from test runner after {total_runs} tests");
}
