// Copyright 2023 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use crate::helpers::*;
use anyhow::{anyhow, Context as _, Error};
use fidl::endpoints::{create_proxy, Proxy};
use std::collections::HashMap;
use {
    fidl_fuchsia_component_runner as frunner, fidl_fuchsia_data as fdata, fidl_fuchsia_io as fio,
    fidl_fuchsia_test as ftest, fuchsia_zircon as zx,
};

struct LtpTestDefinition {
    name: String,
    command: String,
}

fn parse_test_definition(test_def: &str) -> LtpTestDefinition {
    let test_def = test_def.trim();
    match test_def.split_once(' ') {
        Some((name, command)) => {
            LtpTestDefinition { name: name.to_string(), command: command.trim().to_string() }
        }
        None => LtpTestDefinition { name: test_def.to_string(), command: test_def.to_string() },
    }
}

async fn read_tests_list(
    start_info: &mut frunner::ComponentStartInfo,
) -> Result<Vec<LtpTestDefinition>, Error> {
    let program = start_info.program.as_ref().unwrap();
    let tests_list_file = get_str_value_from_dict(program, "tests_list")?;
    Ok(read_file_from_component_ns(start_info, &tests_list_file)
        .await
        .with_context(|| format!("Failed to read {}", tests_list_file))?
        .split('\n')
        .filter(|s| !s.is_empty())
        .map(parse_test_definition)
        .collect())
}

pub async fn get_cases_list_for_ltp(
    mut start_info: frunner::ComponentStartInfo,
) -> Result<Vec<ftest::Case>, Error> {
    let tests_list = read_tests_list(&mut start_info)
        .await?
        .iter()
        .map(|t| t.name.clone())
        .collect::<Vec<String>>();

    Ok(tests_list
        .iter()
        .map(|name| ftest::Case { name: Some(name.clone()), ..Default::default() })
        .collect())
}

pub async fn run_ltp_cases(
    tests: Vec<ftest::Invocation>,
    mut start_info: frunner::ComponentStartInfo,
    run_listener_proxy: &ftest::RunListenerProxy,
    component_runner: &frunner::ComponentRunnerProxy,
) -> Result<(), Error> {
    let program = start_info.program.as_ref().unwrap();
    let base_path = get_str_value_from_dict(program, "tests_dir")?;

    let mut test_commands = HashMap::<String, String>::new();
    read_tests_list(&mut start_info).await?.drain(..).for_each(|t| {
        test_commands.insert(t.name, t.command);
    });

    let file_content =
        read_file_from_component_ns(&mut start_info, "data/test_results.json").await?;
    let expected_test_results: HashMap<String, String> = serde_json::from_str(&file_content)?;

    for test in tests {
        let test_name = test.name.as_ref().expect("No test name");
        let test_command: &String = test_commands
            .get(test_name)
            .ok_or_else(|| anyhow!("Invalid test name: {}", test_name))?;
        let command = vec!["/bin/sh", "-c", test_command];

        let (component_controller, std_handles) =
            start_command(&mut start_info, component_runner, &base_path, &command)?;

        let (case_listener_proxy, case_listener) = create_proxy::<ftest::CaseListenerMarker>()?;
        run_listener_proxy.on_test_case_started(&test, std_handles, case_listener)?;

        let allow_skipped = expected_test_results[test_name] == "IGNORED";
        let result =
            read_ltp_test_result(component_controller.take_event_stream(), allow_skipped).await;
        case_listener_proxy.finished(&result)?;
    }

    Ok(())
}

async fn read_file_from_dir(dir: &fio::DirectoryProxy, path: &str) -> Result<String, Error> {
    let file_proxy = fuchsia_fs::directory::open_file_no_describe(
        &dir,
        path,
        fuchsia_fs::OpenFlags::RIGHT_READABLE,
    )?;
    fuchsia_fs::file::read_to_string(&file_proxy).await.map_err(Into::into)
}

async fn read_file_from_component_ns(
    start_info: &mut frunner::ComponentStartInfo,
    path: &str,
) -> Result<String, Error> {
    for entry in start_info.ns.as_mut().ok_or(anyhow!("Component NS is not set"))?.iter_mut() {
        if entry.path == Some("/pkg".to_string()) {
            let dir = entry.directory.take().ok_or(anyhow!("NS entry directory is not set"))?;
            let dir_proxy = dir.into_proxy()?;

            let result = read_file_from_dir(&dir_proxy, path).await;

            // Return the directory back to the `start_info`.
            entry.directory = Some(fidl::endpoints::ClientEnd::new(
                dir_proxy.into_channel().unwrap().into_zx_channel(),
            ));

            return result;
        }
    }

    Err(anyhow!("/pkg is not in the namespace"))
}

// Starts a component that runs the specified `binary` with the specified `args`.
fn start_command(
    base_start_info: &mut frunner::ComponentStartInfo,
    component_runner: &frunner::ComponentRunnerProxy,
    cwd: &str,
    command: &[&str],
) -> Result<(frunner::ComponentControllerProxy, ftest::StdHandles), Error> {
    let mut program_entries = vec![
        fdata::DictionaryEntry {
            key: "cwd".to_string(),
            value: Some(Box::new(fdata::DictionaryValue::Str(cwd.to_string()))),
        },
        fdata::DictionaryEntry {
            key: "binary".to_string(),
            value: Some(Box::new(fdata::DictionaryValue::Str(command[0].to_string()))),
        },
        fdata::DictionaryEntry {
            key: "args".to_string(),
            value: Some(Box::new(fdata::DictionaryValue::StrVec(
                command.iter().skip(1).map(|s| s.to_string()).collect::<Vec<String>>(),
            ))),
        },
    ];

    // Copy "environ" and "uid" from `base_start_info`.
    if let Some(fidl_fuchsia_data::Dictionary { entries: Some(entries), .. }) =
        base_start_info.program.as_ref()
    {
        for entry in entries {
            match entry.key.as_str() {
                "environ" | "uid" => {
                    program_entries.push(entry.clone());
                }
                _ => (),
            }
        }
    }

    let (numbered_handles, std_handles) = create_numbered_handles();
    let start_info = frunner::ComponentStartInfo {
        program: Some(fidl_fuchsia_data::Dictionary {
            entries: Some(program_entries),
            ..Default::default()
        }),
        numbered_handles,
        ..clone_start_info(base_start_info)?
    };

    Ok((start_test_component(start_info, component_runner)?, std_handles))
}

async fn read_ltp_test_result(
    event_stream: frunner::ComponentControllerEventStream,
    allow_skipped: bool,
) -> ftest::Result_ {
    // Base value used by the ComponentRunner implementation in Starnix to
    // return non-zero error codes (see src/starnix/kernel/execution/component_runner.rs ).
    //
    // TODO(https://fxbug.dev/42081234): Cleanup this once we have a proper mechanism to
    // get Linux exit code from component runner.
    const COMPONENT_EXIT_CODE_BASE: i32 = 1024;

    // Status code used by LTP tests for skipped tests. See
    // https://github.com/linux-test-project/ltp/blob/master/include/tst_res_flags.h .
    const LTP_RESULT_TCONF: i32 = COMPONENT_EXIT_CODE_BASE + 32;

    match read_component_epitaph(event_stream).await {
        zx::Status::OK => {
            ftest::Result_ { status: Some(ftest::Status::Passed), ..Default::default() }
        }
        status if status.into_raw() == LTP_RESULT_TCONF && allow_skipped => {
            ftest::Result_ { status: Some(ftest::Status::Skipped), ..Default::default() }
        }
        _ => ftest::Result_ { status: Some(ftest::Status::Failed), ..Default::default() },
    }
}
