import { fileURLToPath } from "node:url";
import path from "upath";

const { join } = path;

/**
 * Represents the context of the build system.
 */
export class Context
{
    /**
     * The directory containing the source files.
     */
    private sourceRoot = "src";

    /**
     * The directory containing the built files.
     */
    private outRoot = "lib";

    /**
     * The name of the directory containing static assets.
     */
    private staticRoot = "static";

    /**
     * The name of the directory containing javascript files.
     */
    private jsDir = "js";

    /**
     * The name of the directory containing css files.
     */
    private styleDir = "styles";

    /**
     * The name of the directory containing assets.
     */
    private assetDir = "assets";

    /**
     * Initializes a new instance of the {@link Context `Context`} class.
     */
    public constructor() { }

    /**
     * Gets the path to the root of the project.
     */
    public get ProjectRoot(): string
    {
        return join(fileURLToPath(new URL(".", import.meta.url)), "..");
    }

    /**
     * Gets the directory containing the source files.
     */
    public get SourceRoot(): string
    {
        return join(this.ProjectRoot, this.sourceRoot);
    }

    /**
     * Gets the directory containing the built files.
     */
    public get OutRoot(): string
    {
        return join(this.ProjectRoot, this.outRoot);
    }

    /**
     * Gets the path of the directory containing static assets.
     */
    public get StaticRoot(): string
    {
        return join(this.OutRoot, this.staticRoot);
    }

    /**
     * Gets the name of the directory containing javascript files.
     */
    public get JSDirName(): string
    {
        return this.jsDir;
    }

    /**
     * Gets the name of the directory containing css files.
     */
    public get StyleDirName(): string
    {
        return this.styleDir;
    }

    /**
     * Gets the name of the directory containing assets.
     */
    public get AssetDirName(): string
    {
        return this.assetDir;
    }

    /**
     * Creates a path relative to the {@link SourceRoot `SourceRoot`}.
     *
     * @param path
     * The path to join.
     *
     * @returns
     * The resulting path.
     */
    public SourcePath(...path: string[]): string
    {
        return join(this.SourceRoot, ...path);
    }

    /**
     * Creates a path relative to the {@link OutRoot `OutRoot`}.
     *
     * @param path
     * The path to join.
     *
     * @returns
     * The resulting path.
     */
    public OutPath(...path: string[]): string
    {
        return join(this.OutRoot, ...path);
    }

    /**
     * Creates a path relative to the {@link StaticRoot `StaticRoot`}.
     *
     * @param path
     * The path to join.
     *
     * @returns
     * The resulting path.
     */
    public StaticPath(...path: string[]): string
    {
        return join(this.StaticRoot, ...path);
    }
}