# This network generates a random mix of tor versions each time it is run
# You'll need at least 8 runs to cover all possibilities

import random
rng = random.SystemRandom()

# We have to use the same tags for old and new versions, otherwise switching
# between them at random does not work
OLD_TOR="tor-stable"

# By default, Authorities are not configured as exits
Authority = Node(tag="a", authority=1, relay=1, torrc="authority.tmpl")
OldAuthority = Node(tag="a", authority=1, relay=1, torrc="authority.tmpl",
                    tor=OLD_TOR)

NonExitRelay = Node(tag="r", relay=1, torrc="relay-non-exit.tmpl")
OldNonExitRelay = Node(tag="r", relay=1, torrc="relay-non-exit.tmpl",
                       tor=OLD_TOR)

Client = Node(tag="c", torrc="client.tmpl")
OldClient = Node(tag="c", torrc="client.tmpl", tor=OLD_TOR)

HS = Node(tag="h", hs=1, torrc="hs.tmpl")
OldHS = Node(tag="h", hs=1, torrc="hs.tmpl", tor=OLD_TOR)

# Choose old or new Relay, Client, and HS at random
OldNewNonExitRelay = rng.choice([OldNonExitRelay, NonExitRelay])
OldNewClient = rng.choice([OldClient, Client])
OldNewHS = rng.choice([OldHS, HS])

def version(node):
  if node._env["tor"] == Authority._env["tor"]:
    return "new"
  elif node._env["tor"] == OldAuthority._env["tor"]:
    return "old"
  else:
    return "unk"

# Every time chutney takes an action, it will pick versions at random
# It will likely choose different versions for each action
# This could be confusing, so log a message each time
print(("Chose 1 %s authority, 1 %s authority, %d %s non-exit relay, " +
       "%d %s non-exit relay, 1 %s client and 1 %s hidden service")
      % (version(Authority),
         version(OldAuthority),
         2 if OldNewNonExitRelay == NonExitRelay else 1,
	 version(NonExitRelay),
         2 if OldNewNonExitRelay == OldNonExitRelay else 1,
	 version(OldNonExitRelay),
	 version(OldNewClient),
         version(OldNewHS)))

# A hidden service needs 5 authorities/relays to ensure it can build HS
# connections:
# a minimum path length of 3, plus the client-nominated rendezvous point,
# plus a seperate introduction point
NODES = Authority.getN(1) + OldAuthority.getN(1) + NonExitRelay.getN(1) + \
        OldNonExitRelay.getN(1) + OldNewNonExitRelay.getN(1) + \
        OldNewClient.getN(1) + OldNewHS.getN(1)

ConfigureNodes(NODES)