// Copyright 2022, The Android Open Source Project
//
// 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
//
//     http://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.

//! Functions for creating and collecting atoms.

use android_system_virtualizationcommon::aidl::android::system::virtualizationcommon::DeathReason::DeathReason;
use android_system_virtualizationservice_internal::aidl::android::system::virtualizationservice_internal::{
    AtomVmBooted::AtomVmBooted,
    AtomVmCreationRequested::AtomVmCreationRequested,
    AtomVmExited::AtomVmExited,
};
use anyhow::Result;
use log::{trace, warn};
use rustutils::system_properties::PropertyWatcher;
use statslog_virtualization_rust::{vm_booted, vm_creation_requested, vm_exited};

pub fn forward_vm_creation_atom(atom: &AtomVmCreationRequested) {
    let config_type = match atom.configType {
        x if x == vm_creation_requested::ConfigType::VirtualMachineAppConfig as i32 => {
            vm_creation_requested::ConfigType::VirtualMachineAppConfig
        }
        x if x == vm_creation_requested::ConfigType::VirtualMachineRawConfig as i32 => {
            vm_creation_requested::ConfigType::VirtualMachineRawConfig
        }
        _ => vm_creation_requested::ConfigType::UnknownConfig,
    };
    let vm_creation_requested = vm_creation_requested::VmCreationRequested {
        uid: atom.uid,
        vm_identifier: &atom.vmIdentifier,
        hypervisor: vm_creation_requested::Hypervisor::Pkvm,
        is_protected: atom.isProtected,
        creation_succeeded: atom.creationSucceeded,
        binder_exception_code: atom.binderExceptionCode,
        config_type,
        num_cpus: atom.numCpus,
        cpu_affinity: "", // deprecated
        memory_mib: atom.memoryMib,
        apexes: &atom.apexes,
        // TODO(seungjaeyoo) Fill information about task_profile
        // TODO(seungjaeyoo) Fill information about disk_image for raw config
    };

    wait_for_statsd().unwrap_or_else(|e| warn!("failed to wait for statsd with error: {}", e));
    match vm_creation_requested.stats_write() {
        Err(e) => warn!("statslog_rust failed with error: {}", e),
        Ok(_) => trace!("statslog_rust succeeded for virtualization service"),
    }
}

pub fn forward_vm_booted_atom(atom: &AtomVmBooted) {
    let vm_booted = vm_booted::VmBooted {
        uid: atom.uid,
        vm_identifier: &atom.vmIdentifier,
        elapsed_time_millis: atom.elapsedTimeMillis,
    };

    wait_for_statsd().unwrap_or_else(|e| warn!("failed to wait for statsd with error: {}", e));
    match vm_booted.stats_write() {
        Err(e) => warn!("statslog_rust failed with error: {}", e),
        Ok(_) => trace!("statslog_rust succeeded for virtualization service"),
    }
}

pub fn forward_vm_exited_atom(atom: &AtomVmExited) {
    let death_reason = match atom.deathReason {
        DeathReason::INFRASTRUCTURE_ERROR => vm_exited::DeathReason::InfrastructureError,
        DeathReason::KILLED => vm_exited::DeathReason::Killed,
        DeathReason::UNKNOWN => vm_exited::DeathReason::Unknown,
        DeathReason::SHUTDOWN => vm_exited::DeathReason::Shutdown,
        DeathReason::START_FAILED => vm_exited::DeathReason::Error,
        DeathReason::REBOOT => vm_exited::DeathReason::Reboot,
        DeathReason::CRASH => vm_exited::DeathReason::Crash,
        DeathReason::PVM_FIRMWARE_PUBLIC_KEY_MISMATCH => {
            vm_exited::DeathReason::PvmFirmwarePublicKeyMismatch
        }
        DeathReason::PVM_FIRMWARE_INSTANCE_IMAGE_CHANGED => {
            vm_exited::DeathReason::PvmFirmwareInstanceImageChanged
        }
        DeathReason::MICRODROID_FAILED_TO_CONNECT_TO_VIRTUALIZATION_SERVICE => {
            vm_exited::DeathReason::MicrodroidFailedToConnectToVirtualizationService
        }
        DeathReason::MICRODROID_PAYLOAD_HAS_CHANGED => {
            vm_exited::DeathReason::MicrodroidPayloadHasChanged
        }
        DeathReason::MICRODROID_PAYLOAD_VERIFICATION_FAILED => {
            vm_exited::DeathReason::MicrodroidPayloadVerificationFailed
        }
        DeathReason::MICRODROID_INVALID_PAYLOAD_CONFIG => {
            vm_exited::DeathReason::MicrodroidInvalidPayloadConfig
        }
        DeathReason::MICRODROID_UNKNOWN_RUNTIME_ERROR => {
            vm_exited::DeathReason::MicrodroidUnknownRuntimeError
        }
        DeathReason::HANGUP => vm_exited::DeathReason::Hangup,
        _ => vm_exited::DeathReason::Unknown,
    };

    let vm_exited = vm_exited::VmExited {
        uid: atom.uid,
        vm_identifier: &atom.vmIdentifier,
        elapsed_time_millis: atom.elapsedTimeMillis,
        death_reason,
        guest_time_millis: atom.guestTimeMillis,
        rss_vm_kb: atom.rssVmKb,
        rss_crosvm_kb: atom.rssCrosvmKb,
        exit_signal: atom.exitSignal,
    };

    wait_for_statsd().unwrap_or_else(|e| warn!("failed to wait for statsd with error: {}", e));
    match vm_exited.stats_write() {
        Err(e) => warn!("statslog_rust failed with error: {}", e),
        Ok(_) => trace!("statslog_rust succeeded for virtualization service"),
    }
}

fn wait_for_statsd() -> Result<()> {
    PropertyWatcher::new("init.svc.statsd")?.wait_for_value("running", None)?;
    Ok(())
}
