import tohu
from tohu import *
from utils import print_generated_sequence

print(f"Tohu version: {tohu.__version__}")

"""
Explanation: Regression tests
End of explanation
"""


class FoobarGenerator(CustomGenerator):
    a = Integer(low=1000, high=3000)
    b = Sequential(prefix="Foo_", digits=2)
    c = Float(low=1.0, high=4.0)

g1 = FoobarGenerator()
g2 = FoobarGenerator()

"""
Explanation: Resetting one generator should not reset others of the same type
Let's create two generators of the same type.
End of explanation
"""


g1.reset(seed=12345)
g2.reset(seed=9999)
print_generated_sequence(g1, num=3, sep='\n')
print_generated_sequence(g2, num=3, sep='\n')

print("-------------------------------------------------")

g1.reset(seed=12345)
g2.reset(seed=9999)
g1.reset(seed=12345)
print_generated_sequence(g1, num=3, sep='\n')
print_generated_sequence(g2, num=3, sep='\n')

"""
Explanation: The random generators which produce the attributes of items generated by g1 and g2 must be independent of each other. This regression test checks this by making sure that g1.reset() does not interfere with g2.reset(). In particular, the two outputs below should be identical (because the final call g1.reset(12345) should not interfere with the previous call g2.reset(9999)).
End of explanation
"""


class FoobarGenerator(CustomGenerator):
    a1 = HashDigest(length=8)
    a2 = HashDigest(length=8)
    a3 = HashDigest(length=8)
    
    b1 = Integer(low=0, high=1000)
    b2 = Integer(low=0, high=1000)
    b3 = Integer(low=0, high=1000)

g = FoobarGenerator()

g.reset(seed=99999)
print_generated_sequence(g, num=10, sep='\n')

"""
Explanation: Sub-generators of custom generator should be initialised with separate seeds
Each custom generator can be re-initialised using a given seed. Internally, this re-initialises each of the constituent generators. This test checks that different seeds are used for each of the individual generators, even if they are of the same type (otherwise the values produced for each attribute would be the same). In particular, the sequences produced for a1, a2, a3 below should be different (and similarly for (b1, b2, b3).
End of explanation
"""


g = NumpyRandomGenerator(method="normal", loc=3.0, scale=5.0)
g.reset(seed=12345); print_generated_sequence(g, num=4)
g.reset(seed=99999); print_generated_sequence(g, num=4)

g1 = NumpyRandomGenerator(method="normal", loc=3.0, scale=5.0)
g2 = NumpyRandomGenerator(method="normal", loc=3.0, scale=5.0)
g1.reset(seed=12345)
g2.reset(seed=99999)
print_generated_sequence(g1, num=4)
print_generated_sequence(g2, num=4)

"""
Explanation: NumpyRandomGenerator
This is a quick sanity check that resetting a NumpyRandomGenerator really fully resets the state and leads to independent runs.
End of explanation
"""


g1 = Integer(0, 100)
g2 = Integer(0, 100)
g1.reset(12345)
g2.reset(12345)

print_generated_sequence(g1, num=10)
print_generated_sequence(g2, num=10)

z = Zip(g1, g2)
h1, h2 = Split(z)

"""
Explanation: Zip should use different seeds internally to reset its input generators
End of explanation
"""


z.reset(seed=12345)
print_generated_sequence(h1, num=10)
print_generated_sequence(h2, num=10)

"""
Explanation: If .reset() is called on a Zip generator, it should use different seeds internally to reset each of its constituent input generators. In particular, the output of h1 and h2 below should be different.
End of explanation
"""


g1 = FakerGenerator(method="name")
g2 = FakerGenerator(method="name")
g1.reset(seed=12345)
g2.reset(seed=12345)

print_generated_sequence(g1, num=5)
print_generated_sequence(g2, num=5)

"""
Explanation: Multiple FakerGenerator instances should be independent
End of explanation
"""


