"""
Test: Christodoulou-Rovelli black hole interior volume growth
=============================================================

Standard GR result (Christodoulou & Rovelli 2015):
For a Schwarzschild black hole of mass M, the volume of the maximal
spacelike slice anchored at horizon advanced time v grows as:

    V(v) -> 3*sqrt(3) * pi * M^2 * v  (in G=c=1 units)  as v -> infinity

In SI-ish units with G, c restored:
    V(v) -> 3*sqrt(3) * pi * (GM/c^2)^2 * c * v
          = 3*sqrt(3) * pi * R_s^2/4 * c * v
          = (3*sqrt(3)/4) * pi * R_s^2 * c * v

The derivation uses the interior Schwarzschild metric, finds the maximal
slice (one that extremises volume), and computes its proper volume.

Framework picture:
------------------
A black hole is a region of the 3-brane with extreme embedding in w4.
Inside the horizon, the r coordinate becomes timelike (the "advance"
direction). The w4 embedding-depth of the brane increases as advanced
time v on the horizon increases -- the brane gets "longer" in the
ambient direction.

The "interior volume" that CR compute is the proper volume of the
maximal spacelike slice. In the framework, this should correspond to
integrating the framework's proper volume element over a slice that
extends into the increasingly w4-extended embedded region.

Concretely: we compute the proper volume of the maximal slice directly
from the Schwarzschild interior metric (which is just GR, and which the
framework reads as describing brane geometry). The question is whether
the asymptotic growth rate is the CR coefficient.

If it is, the framework passes the test: the "interior volume grows
linearly with age" result, which looks mysterious in the standard
causal-structure picture, is recovered as a direct statement about
brane embedding extending in w4 as v increases.
"""

import numpy as np
from scipy.integrate import quad
from scipy.optimize import minimize_scalar

# Units: G = c = 1, M = 1 so R_s = 2
M = 1.0
Rs = 2.0 * M

print("="*72)
print("TEST: Christodoulou-Rovelli interior volume growth")
print("="*72)
print(f"Units: G = c = 1, M = {M}, R_s = {Rs}")
print()

# Schwarzschild interior metric (inside horizon, r < Rs, t and r swap roles):
#   ds^2 = -(Rs/r - 1)^-1 dr^2 + (Rs/r - 1) dt^2 + r^2 dOmega^2
# Here r is timelike and runs from Rs down to 0; t is spacelike.
#
# A spacelike slice inside the horizon is parameterised by r(t_slice).
# The induced 3-metric on a slice r = r(T), with T a parameter,
# has proper volume element:
#   dV = sqrt( (Rs/r - 1) - (Rs/r - 1)^-1 (dr/dT)^2 ) * r^2 sin(theta) dT dtheta dphi
#
# The MAXIMAL slice extremises volume. For the Schwarzschild interior
# this is r = 3M/2 (a famous result: the maximal slice sits at r = 3M/2
# for large v).
#
# At r = 3M/2:
#   (Rs/r - 1) = (2M/(3M/2) - 1) = 4/3 - 1 = 1/3
#   so the "lapse"-like factor on the slice is sqrt(1/3)
# The slice has r^2 = 9M^2/4, surface area 4*pi*r^2 = 9*pi*M^2
# The proper length along t on the slice extends over a range determined
# by v (the advanced time at which the slice is anchored at the horizon).

# For the maximal slice anchored at advanced time v, the proper volume is:
#   V(v) = 4*pi * r_m^2 * sqrt(f(r_m)) * L(v)
# where r_m = 3M/2, f(r_m) = |g_tt| on the slice = 1/3, and L(v) is the
# proper length of the slice in the t direction.
#
# Christodoulou-Rovelli show that for large v,
#   L(v) -> v / sqrt(|g_tt(r_m)|) scaled appropriately
# giving V(v) -> 3*sqrt(3)*pi*M^2 * v

# Let's compute this directly.

# The maximal slice condition: extremise
#   V[r(T)] = int sqrt( f(r) - f(r)^-1 (dr/dT)^2 ) r^2 dT
# where f(r) = Rs/r - 1 inside horizon.

def f(r):
    """Inside-horizon factor: f(r) = Rs/r - 1, positive for r < Rs."""
    return Rs/r - 1.0

# The maximal slice for Schwarzschild interior has constant r = r_m where
# r_m extremises r^2 * sqrt(f(r)):
#   d/dr [ r^2 sqrt(Rs/r - 1) ] = 0
#   d/dr [ r^2 sqrt((Rs - r)/r) ] = 0
#   d/dr [ r sqrt(r(Rs - r)) ] = 0
# Let's solve numerically:

def volume_integrand(r):
    """r^2 * sqrt(f(r)) -- the thing we extremise for the maximal slice."""
    if r >= Rs or r <= 0:
        return 0.0
    return r**2 * np.sqrt(f(r))

# Find maximum:
result = minimize_scalar(lambda r: -volume_integrand(r), 
                         bounds=(0.01*Rs, 0.99*Rs), 
                         method='bounded')
r_max = result.x
val_max = -result.fun
print(f"Maximal slice radius: r_m = {r_max:.6f}")
print(f"Expected (3M/2):      r_m = {1.5*M:.6f}")
print(f"Match: {np.isclose(r_max, 1.5*M, rtol=1e-4)}")
print()

# On the maximal slice r = 3M/2:
#   f(r_m) = 1/3
#   r_m^2 = 9M^2/4
#   sqrt(f(r_m)) = 1/sqrt(3)
#   r_m^2 * sqrt(f(r_m)) = (9M^2/4) / sqrt(3) = 9M^2/(4*sqrt(3)) = 3*sqrt(3)*M^2/4
r_m = 1.5*M
coefficient_per_unit_length = 4*np.pi * r_m**2 * np.sqrt(f(r_m))
print(f"Area factor 4*pi*r_m^2 = {4*np.pi*r_m**2:.6f} = 9*pi*M^2 = {9*np.pi*M**2:.6f}")
print(f"Per-unit-proper-length volume coefficient: 4*pi*r_m^2*sqrt(f(r_m)) = {coefficient_per_unit_length:.6f}")
print(f"Expected 3*sqrt(3)*pi*M^2 = {3*np.sqrt(3)*np.pi*M**2:.6f}")
print(f"Match: {np.isclose(coefficient_per_unit_length, 3*np.sqrt(3)*np.pi*M**2, rtol=1e-6)}")
print()

# So if the maximal slice has proper length L in the t-direction, 
# volume = 3*sqrt(3)*pi*M^2 * L.
# 
# The CR result is that L -> v for large v, where v is advanced time 
# on the horizon. So V(v) -> 3*sqrt(3)*pi*M^2 * v.
#
# This is pure GR. Now the framework question:
# Can we read this as a statement about the brane's w4 embedding?

print("="*72)
print("FRAMEWORK INTERPRETATION")
print("="*72)
print()
print("In standard GR, the interior r-coordinate becomes timelike, and")
print("the maximal-slice volume grows linearly with advanced time v.")
print()
print("Framework reading:")
print("- The brane's embedding in w4 inside the horizon extends further")
print("  into the ambient direction as v (brane-time at the horizon)")
print("  advances.")
print("- The rate of w4 advance inside the horizon is differential: the")
print("  embedding lengthens at a rate determined by the local geometry.")
print("- The maximal-slice volume is the proper 3-volume of a slice of")
print("  the embedded region at a given v.")
print("- That this volume grows *linearly* in v with coefficient 3*sqrt(3)*pi*M^2")
print("  is read as: the extremal slice sits at r_m = 3M/2, which is where")
print("  the embedding's 'width' (r^2) and 'depth-rate' (sqrt(f)) combine")
print("  to extremise volume per unit v.")
print()
print("Is this a framework *derivation*? No -- the coefficient 3*sqrt(3)*pi*M^2")
print("comes from the Schwarzschild metric (standard GR). The framework reads")
print("it rather than deriving it.")
print()
print("Is it a framework *recovery*? Yes -- the linear-in-v growth is")
print("geometrically natural under the embedding picture: the brane extends")
print("in w4 at a rate proportional to the horizon advance rate, and the")
print("maximal slice extremises proper volume within that extending region.")
print()
print("The 'puzzle' (why volume grows while horizon area stays constant) is")
print("dissolved: horizon area is brane surface at the embedded-region")
print("boundary (static); interior volume is the w4-extended embedding itself")
print("(growing). These are different geometric quantities in the framework,")
print("so their different behaviours are expected, not paradoxical.")
print()
print("VERDICT: Framework consistent with CR. It gives the right linear-in-v")
print("scaling with the right coefficient (because it's reading the same")
print("Schwarzschild metric GR uses). The framework's contribution is")
print("*dissolving the paradox* -- not deriving a new number.")
