using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;

namespace MyParking.Shared
{
    // 编队固定布局快照，车队坐标系原点就是编队参考中心。
    public sealed class FleetLayout
    {
        private readonly ReadOnlyCollection<VehicleLayout> _vehicles;

        public FleetLayout(IReadOnlyList<VehicleLayout> vehicles)
        {
            if (vehicles == null)
            {
                throw new ArgumentNullException(nameof(vehicles));
            }

            if (vehicles.Count == 0)
            {
                throw new ArgumentException(
                    "编队布局至少需要包含一辆车。",
                    nameof(vehicles));
            }

            var snapshot = new VehicleLayout[vehicles.Count];
            var vehicleIds = new HashSet<int>();

            for (var index = 0; index < vehicles.Count; index++)
            {
                var vehicle = vehicles[index];
                if (vehicle.VehicleId <= 0)
                {
                    throw new ArgumentOutOfRangeException(
                        nameof(vehicles),
                        $"第{index}辆车的编号必须大于零。");
                }

                if (!vehicleIds.Add(vehicle.VehicleId))
                {
                    throw new ArgumentException(
                        $"编队布局包含重复车号{vehicle.VehicleId}。",
                        nameof(vehicles));
                }

                NumericGuard.EnsureFinite(
                    vehicle.PoseInFleet,
                    $"{nameof(vehicles)}[{index}].{nameof(VehicleLayout.PoseInFleet)}");
                snapshot[index] = vehicle;
            }

            _vehicles = Array.AsReadOnly(snapshot);
        }

        public IReadOnlyList<VehicleLayout> Vehicles => _vehicles;

        public int VehicleCount => _vehicles.Count;

        public bool TryGetVehicle(
            int vehicleId,
            out VehicleLayout vehicle)
        {
            for (var index = 0; index < _vehicles.Count; index++)
            {
                if (_vehicles[index].VehicleId == vehicleId)
                {
                    vehicle = _vehicles[index];
                    return true;
                }
            }

            vehicle = default;
            return false;
        }
    }
}
