// =============================================================================
// Tesla.Contract — Shared RPC Wire Contract  (assembly: TeslaConsoleLaunchLib)
// =============================================================================
// Single source of truth for the Console <-> Launcher protocol. Previously this
// lived in two hand-synced places: the vendored binary
// Console/lib/TeslaConsoleLaunchLib.dll (consumed by the Console) and a manual
// replica in Launcher/LaunchModels_Shared.cs (consumed by the Launcher Service).
//
// The wire types below are reconstructed verbatim from the original
// TeslaConsoleLaunchLib.dll. Field NAMES, TYPES and ORDER are load-bearing:
// they are serialized with BinaryFormatter and must match byte-for-byte or the
// protocol breaks silently at runtime. The byte-identical guarantee is asserted
// by WireContractCompatTests in the differential suite.
//
// This file is compiled for BOTH net48 (Console) and net6.0-windows (Launcher).
// The TCP/OFB/BinaryFormatter client (PodManagerConnection) is net48-only and
// lives under Client/ — it depends on TeslaSecureConfiguration.dll.
// =============================================================================

using System;
using System.Net;
using System.Reflection;

namespace Tesla.Net
{
    /// <summary>App identifier + display name pair.</summary>
    [Serializable]
    public struct LaunchPair
    {
        public Guid LaunchKey;

        public string DisplayName;
    }

    /// <summary>Describes one launchable simulation application.</summary>
    [Serializable]
    public struct LaunchData
    {
        public LaunchPair LaunchPair;

        public string WorkingDirectory;

        public string ExeFile;

        public string Arguments;

        public bool AutoRestart;
    }

    /// <summary>Tracks a currently running simulation process.</summary>
    [Serializable]
    public struct LaunchedAppData
    {
        public int ProcessId;

        public Guid LaunchKey;
    }

    /// <summary>Progress of an out-of-band product installation.</summary>
    [Serializable]
    public struct OutOfBandProgress
    {
        public int PercentComplete;

        public string Status;

        public bool IsCompleted;
    }

    /// <summary>Complete pod state snapshot for the FullUpdate RPC.</summary>
    [Serializable]
    public struct FullUpdateData
    {
        public LaunchData[] InstalledApps;

        public LaunchedAppData[] LaunchedApps;

        public float VolumeLevel;
    }

    /// <summary>RPC command from the Console. Function is a MethodBase of ILauncherService.</summary>
    [Serializable]
    public struct InvokeCommand
    {
        public MethodBase Function;

        public object[] Parameters;
    }

    /// <summary>RPC result returned to the Console.</summary>
    [Serializable]
    public struct InvokeResult
    {
        public object Result;

        public Exception Exception;

        public TimeSpan CallDuration;
    }

    public delegate void OutOfBandProgressChanged(Guid outOfBandCallId, OutOfBandProgress progress);

    /// <summary>Server-side RPC surface. Method signatures are resolved by name from a
    /// serialized MethodBase, so they must match the original exactly.</summary>
    public interface ILauncherService
    {
        float VolumeLevel { get; set; }

        void ClearStore();

        DateTime Ping(DateTime now);

        Guid InitiateInstallProduct();

        OutOfBandProgress GetOutOfBandProgress(Guid invokeCallId);

        int LaunchApp(Guid launchKey);

        LaunchPair[] GetLaunchableApps();

        void KillApp(Guid launchKey, int processId);

        void KillAllOfType(Guid launchKey);

        void KillAllApps();

        void Shutdown(bool restart);

        LaunchedAppData[] GetLaunchedApps();

        LaunchData[] GetInstalledApps();

        void RemoveApp(Guid index);

        void InstallApp(LaunchData data);

        void UninstallApp(Guid launchKey);

        FullUpdateData FullUpdate();
    }

    /// <summary>Console-side connection: ILauncherService plus connection management
    /// and the out-of-band InstallProduct file transfer.</summary>
    public interface IPodManagerConnection : ILauncherService
    {
        bool IsOpen { get; }

        void Open(IPEndPoint remoteEndPoint, byte[] secureKey);

        void Close();

        Guid InstallProduct(string filename);
    }
}

namespace TeslaConsole
{
    /// <summary>Thrown by the Console-side connection when the pod link drops.</summary>
    [Serializable]
    public class ConnectionLostException : Exception
    {
        public ConnectionLostException()
        {
        }

        public ConnectionLostException(string message)
            : base(message)
        {
        }

        public ConnectionLostException(string message, Exception innerException)
            : base(message, innerException)
        {
        }
    }
}
