/**
 * RootContext - Propagated through component tree via _receiveContext
 *
 * Provides root (DNS-hierarchical addressing root) information to all
 * components in the tree. Created by <matrix-dsl> element, cascades to
 * all children.
 *
 * Renamed from RealmContext: "realm" was a flat single-token namespace;
 * "root" is a DNS-derived hierarchical root (e.g., 'com.nimbletec.richard.santomauro').
 */

/**
 * Federation mode determines how the root connects to transports.
 */
export type FederationMode = 'auto' | 'local' | 'public' | 'disabled';

/**
 * Context object propagated through component tree.
 */
export interface RootContext {
  /**
   * Full root name including tab suffix (e.g., "flowpad.tab-a1b2c3d4")
   */
  root: string;

  /**
   * Base root without tab suffix (e.g., "flowpad")
   * Used for display and cross-tab coordination.
   */
  baseRoot: string;

  /**
   * Federation mode from <matrix-dsl federation="...">
   */
  federation: FederationMode;

  /**
   * Accumulated mount prefix from ancestor chain.
   * Updated by j08g-01-mount-derivation.
   */
  mountPrefix: string;
}

/**
 * Create a RootContext with defaults.
 */
export function createRootContext(
  baseRoot: string,
  federation: FederationMode = 'auto',
  tabRoot?: string
): RootContext {
  return {
    root: tabRoot ?? baseRoot,
    baseRoot,
    federation,
    mountPrefix: '',
  };
}

/**
 * Derive child context with updated mount prefix.
 */
export function deriveRootContext(
  parent: RootContext,
  childMount?: string
): RootContext {
  let mountPrefix = parent.mountPrefix;

  if (childMount) {
    // Absolute mount (//path) overrides
    if (childMount.startsWith('//')) {
      mountPrefix = childMount.slice(1); // Remove one /
    }
    // Relative mount (./path or /path) appends
    else if (childMount.startsWith('./')) {
      mountPrefix = `${mountPrefix}/${childMount.slice(2)}`;
    } else if (childMount.startsWith('/')) {
      mountPrefix = `${mountPrefix}${childMount}`;
    } else {
      mountPrefix = `${mountPrefix}/${childMount}`;
    }

    // Normalize double slashes
    mountPrefix = mountPrefix.replace(/\/+/g, '/');
  }

  return {
    ...parent,
    mountPrefix,
  };
}
