/**
 * ActorServiceProxy — Generic proxy wrapping a contract + mount into IActorService.
 *
 * The proxy transparently handles:
 *   - Contract validation (supports() checks before invoke)
 *   - Bus routing (RequestReply.execute to the mount)
 *   - Local vs remote (same proxy whether in-process or federated)
 *
 * This is COM marshaling — same interface regardless of wire protocol.
 */

import type { IMatrixContext } from './IMatrixContext';
import type { IActorService, ServiceContract } from './ServiceContract';

export class ActorServiceProxy implements IActorService {
  constructor(
    private _ctx: IMatrixContext,
    readonly mount: string,
    readonly contract: ServiceContract,
  ) {}

  /** QueryInterface — does this service support the given operation? */
  supports(op: string): boolean {
    return op in this.contract.ops;
  }

  /** Invoke an operation over the bus. Rejects unknown ops. */
  async invoke(op: string, payload?: Record<string, unknown>): Promise<unknown> {
    if (!this.supports(op)) {
      return { ok: false, error: `${this.contract.id}: operation '${op}' not in contract` };
    }

    // Import RequestReply lazily to avoid circular dependency at module load
    const { RequestReply } = await import('../remoting/RequestReply');
    return RequestReply.execute(this._ctx, this.mount, op, payload ?? {});
  }
}
