#pragma once

// external
#include <toml.hpp>

// internal
#include "poac/config.hpp"
#include "poac/core/builder/data.hpp"
#include "poac/core/resolver/types.hpp" // ResolvedDeps
#include "poac/data/manifest.hpp"
#include "poac/util/format.hpp"
#include "poac/util/log.hpp"
#include "poac/util/result.hpp"
#include "poac/util/rustify.hpp"

namespace poac::core::builder::manifest {

inline constexpr StringRef MANIFEST_FILE_NAME = "ninja.build";
inline constexpr Arr<StringRef, 2> MANIFEST_HEADERS{
    "This file is automatically generated by Poac.",
    "It is not intended for manual editing."};

inline Fn ninja_manifest_last_modified(const Path& build_dir)
    ->fs::file_time_type {
  return fs::last_write_time(build_dir / MANIFEST_FILE_NAME);
}

inline Fn is_outdated(const Path& build_dir)->bool {
  if (!fs::exists(build_dir / MANIFEST_FILE_NAME)) {
    return true;
  }
  using poac::data::manifest::poac_toml_last_modified;
  return ninja_manifest_last_modified(build_dir)
         < poac_toml_last_modified(config::cwd);
}

Fn rebuild(data::NinjaMain& ninja_main, Status& status, String& err)->bool;

Fn gather_includes(const resolver::ResolvedDeps& resolved_deps)->Vec<String>;

Fn get_cfg_profile(const toml::value& poac_manifest)->Vec<toml::table>;

Fn gather_flags(
    const toml::value& poac_manifest, const String& name,
    const Option<String>& prefix = None
)
    ->Vec<String>;

[[nodiscard]] Fn construct(
    const Path& build_dir, const toml::value& poac_manifest,
    const resolver::ResolvedDeps& resolved_deps
)
    ->Result<String>;

[[nodiscard]] Fn create(
    const Path& build_dir, const toml::value& poac_manifest,
    const resolver::ResolvedDeps& resolved_deps
)
    ->Result<void>;

} // namespace poac::core::builder::manifest
