using System;
using System.Collections.Generic;
using System.IO;
using Godot;
using Zio;
namespace TBL.GodotSharp.Content.Package
{
///
/// 基于文件系统的抽象内容包
/// 会在内部自动检索配置文件来获取描述符和依赖项信息
///
public class FileSystemPackage : PackageNode
{
public override IFileSystem SelfFileSystem { get; }
public sealed override Info SelfInfo { get; }
public sealed override IEnumerable Dependencies { get; }
public FileSystemPackage(IFileSystem fileSystem)
{
Dependencies = null;
var iniFound = false;
foreach (var iniPath in fileSystem.EnumeratePaths(UPath.Root, "*.ini", SearchOption.TopDirectoryOnly, SearchTarget.File))
{
var ini = new ConfigFile();
var err = ini.Parse(fileSystem.ReadAllText(iniPath));
if (err != Error.Ok)
throw new GodotException(err);
iniFound = true;
if (SelfInfo.Name.Empty() && ini.HasSection(nameof(SelfInfo)))
{
SelfInfo = new Info(
ini.GetValue(nameof(SelfInfo), nameof(SelfInfo.Name)) as string,
ini.GetValue(nameof(SelfInfo), nameof(SelfInfo.AuthorInfo)) as string,
ini.GetValue(nameof(SelfInfo), nameof(SelfInfo.VersionInfo)) as string
);
}
if (Dependencies == null && ini.HasSection(nameof(Dependencies)))
{
var dependencies = new List();
foreach (var dependencyName in ini.GetSectionKeys(nameof(Dependencies)))
{
var info = ini.GetValue(nameof(Dependencies), dependencyName) as Godot.Collections.Array;
if (info == null || info.Count < 2)
continue;
var flags = DependencyInfo.FlagsEnum.None;
if (info.Count > 2 && info[2] is string flagsInfo)
{
foreach (var flagInfo in flagsInfo.Split(';'))
if (Enum.TryParse(flagInfo.Trim(), out var flag))
flags |= flag;
}
var dependency = new DependencyInfo(new Info(dependencyName, info[0] as string, info[1] as string), flags);
dependencies.Add(dependency);
}
Dependencies = dependencies;
}
if (!SelfInfo.Name.Empty() &&
Dependencies != null)
{
break;
}
}
if (!iniFound)
{
QueueFree();
throw new GodotException(Error.FileNotFound);
}
SelfFileSystem = fileSystem;
}
}
}