import random
import collections
random.seed("something")

class TestGen:
    def __init__(self):
        self.test_number = 0

    def generate_samples(self):
        #1 test
        self.print_sample(3, [(1, 4), (3, 6), (2, 5)], 2, [2, 1])

    def generate_min_tests(self):
        #6 tests
        self.print_test(1, [(1, 1)], 1, [1])
        self.print_test(1, [(1, 2)], 1, [1])
        self.print_test(2, [(1, 2), (2, 3)], 2, [1, 2])
        self.print_test(2, [(1, 3), (2, 4)], 2, [1, 2])
        self.print_test(2, [(2, 3), (1, 2)], 2, [1, 2])
        self.print_test(2, [(2, 4), (1, 3)], 2, [1, 2])
                                                                            
    def generate_tricky_tests(self, maxn, maxx, maxk):
        #1 test
        if maxn <= 10:
            self.print_test(4, [(3, 6), (4, 5), (2, 4), (5, 7)], 5, [1, 2, 3, 4, 3])
        elif maxn <= 500:
            pass
        elif maxn <= maxn:
            pass

    def generate_random_test(self, maxn, maxx, maxk):
        n = maxn
        segs = []
        wasl = collections.defaultdict(int)
        wasr = collections.defaultdict(int)
        for i in range(n):
            l = random.randint(1, maxx)
            r = random.randint(l, maxx)
            while (l in wasl) or (r in wasr):
                l = random.randint(1, maxx)
                r = random.randint(l, maxx)
            wasl[l] = 1
            wasr[r] = 1
            segs.append((l, r))
        k = random.randint(n, maxk)
        qs = []
        for i in range(n):
            qs.append(i + 1)
        for i in range(k - n):
            qs.append(random.randint(1, n))
        random.shuffle(qs)
        self.print_test(n, segs, k, qs)

    #def generate_small_test(self, maxn, maxx, maxk):
    #def generate_medium_test(self, maxn, maxx, maxk):

    def generate_max_tests(self, maxn, maxx, maxk):
        #6 tests
        n = maxn
        segs = []
        for i in range(n):
            segs.append((i + 1, i + 5000))
        random.shuffle(segs)
        qs = [(i % n + 1) for i in range(maxk)]
        random.shuffle(qs)
        self.print_test(n, segs, maxk, qs)
        
        for test_num in range(5):
            sgs = segs
            diffs = random.randint(1, 10)
            for it in range(diffs):
                idx = random.randint(0, n - 1)
                l = random.randint(1, 1000000)
                r = random.randint(l, 1000000)
                sgs[idx] = (l, r)
            self.print_test(n, sgs, maxk, qs)

        for test_num in range(5):
            self.generate_random_test(maxn, maxx, maxk)

    def print_sample(self, n, segs, k, qs):
        self.test_number += 1
        test_name = "../preliminary/" + "{0:0=2d}".format(self.test_number)
        test_file = open(test_name, "w")
        print(n, file=test_file)
        print('\n'.join(' '.join(str(element) for element in segment) for segment in segs), file=test_file)
        print(k, file=test_file)
        print('\n'.join(str(query) for query in qs), file=test_file)
        test_file.close()

    def print_test(self, n, segs, k, qs):
        self.test_number += 1
        test_name = "../tests/" + "{0:0=2d}".format(self.test_number)
        test_file = open(test_name, "w")
        print(n, file=test_file)
        print('\n'.join(' '.join(str(element) for element in segment) for segment in segs), file=test_file)
        print(k, file=test_file)
        print('\n'.join(str(query) for query in qs), file=test_file)
        test_file.close()

    def generate_all_tests(self):
        maxn = 3000
        maxx = 10**9
        maxk = 10**5
        self.generate_samples()                       #1 test
        self.test_number = 0                 

        #First group of tests (01-17)
        self.generate_min_tests()                     #6 tests
        self.generate_tricky_tests(10, 10**9, 20)     #1 tests
        for i in range(5):                            #5 tests
          n = random.randint(5, 10)
          self.generate_random_test(n, 100, n)        #5 tests
        for i in range(5):
          self.generate_random_test(10, 100, 10)

        #Second group of tests (18-27)
        self.generate_tricky_tests(500, 10**9, 500)   #0 tests
        for i in range(5):                            #5 tests
          n = random.randint(200, 500)
          self.generate_random_test(n, 10**9, n)
        for i in range(5):                            #5 tests
          self.generate_random_test(500, 10**9, 500)
        
        #Third group of tests (28-33)
        self.generate_tricky_tests(maxn, maxx, maxk)  #0 tests
        self.generate_max_tests(maxn, maxx, maxk)     #11 tests

import os, shutil
if os.path.exists('../tests'):
    print('Directory tests is already exists')
    shutil.rmtree('../tests', ignore_errors=False, onerror=None)
if os.path.exists('../preliminary'):
    print('Directory preliminary is already exists')
    shutil.rmtree('../preliminary', ignore_errors=False, onerror=None)
try:
    os.makedirs('../preliminary')
    os.makedirs('../tests')
except OSError:
    pass

import time
start = time.time()
writer = TestGen()
writer.generate_all_tests()
finish = time.time()
print('All tests were generated. Elapsed time: ', finish - start)
