import os
import random
import sys
import math

MAX_N = 2*10**5
MAX_X = 10**8
MIN_X = -10**8

CASE = 1
DEST = os.path.join(os.getcwd(), '../data/secret')

def next_file(short_desc=None, long_desc=None):
    global CASE
    basename = os.path.join(DEST, '%02d' % CASE)
    CASE += 1
    if short_desc is not None:
        basename += '-' + short_desc
    if long_desc is not None:
        with open(basename+'.desc', 'w') as desc_out:
            desc_out.write(long_desc)
    return open(basename+'.in', 'w')

def save_case(components, short_desc=None, long_desc=None):
    assert 1 <= len(components) <= MAX_N
    sys.stderr.write('save case n=%d short_desc=%s\n' % (len(components), short_desc))
    f = next_file(short_desc, long_desc)
    random.shuffle(components)
    f.write('%d\n' % len(components))
    for (x, y, c) in components: f.write('%d %d %c\n' % (x, y, c))
    f.close()

def random_component(test_results = "PN-", min_x=MIN_X, max_x=MAX_X, min_y=MIN_X, max_y=MAX_X):
    x = random.randint(min_x, max_x)
    y = random.randint(min_y, max_y)
    c = random.randint(0, len(test_results)-1)
    return (x, y, test_results[c])
    
def random_case(n, test_results = "PN-", min_x=MIN_X, max_x=MAX_X, min_y=MIN_X, max_y=MAX_X):
    return [random_component(test_results, min_x, max_x, min_y, max_y) for _ in range(n)]

def line(n, dx, dy, c, x0 = 0, y0 = 0):
    return [(k*dx + x0, k*dy + y0, c) for k in range(n)]
    
def main():
    random.seed(13)

    save_case(random_case(1, 'P'), 'single_comp')
    save_case(random_case(1, 'N'), 'single_comp')
    save_case(random_case(1, '-'), 'single_comp')
    
    size = 10
    save_case([(0,0,'P'),(1,0,'P'),(2,0,'P')])
    save_case([(0,0,'P'),(2,0,'P'),(1,2,'-')])
    save_case([(-2,-2,'P'),(0,3,'N'),(0,2,'-'),(1,0,'P'),(1,-2,'-'),(2,6,'-'),(2,1,'P'),\
        (2,0,'P'),(2,-3,'P'),(3,1,'N'),(3,-4,'P'),(6,-3,'P'),(7,0,'-'),(8,-2,'P'),(7,-1,'P')])
    save_case(line(size, 2, 1, 'P'),'hor_line_leaking')
    save_case(line(size, 1, 2, 'P'),'ver_line_leaking')
    for size in (20, MAX_N):
        save_case(line(size//2, 1, 0, 'P') + line(size//2, 1, 0, 'N', 0, 1), 'N_over_P')
        save_case(line(size//2, 1, 0, 'N') + line(size//2, 1, 0, 'P', 0, 1), 'P_over_N')
        save_case(line(size//2, 1, 0, 'P') + line(size//2, 1, 0, '-', 0, 2), '-_over_P')
        save_case(random_case(size), 'random')
        save_case(random_case(size, 'P-'), 'random_P-')
        save_case(random_case(size, 'N-'), 'random_N-')
        save_case(random_case(size//2, 'P-', MIN_X, MAX_X, 0, MAX_X) + \
            random_case(size//2, 'P-', MIN_X, MAX_X, -MAX_X, 0), 'random_N_over_P-')
        save_case(random_case(size-2, 'N-', 0, MAX_X, 0, MAX_X) + \
            [(-100,-100,'P'),(-101,-102,'N')], 'impossible')
        save_case(line(size//2, MAX_X//size, 0, 'P') + \
            random_case(size//2, "-", 0, MAX_X, 1, MAX_X//size*5), 'random_-_over_P')
        save_case(line(size//2, MAX_X//size, 0, 'P') + \
            random_case(size//2, "N-", 0, MAX_X, 1, MAX_X//size*5), 'random_N-_over_P')
        save_case(random_case(size,"P-", 0, 1000, MIN_X, MAX_X), 'vertical_band_P-')
        save_case(random_case(size,"P-", MIN_X, MAX_X, 0, 1000), 'horizontal_band_P-')

    for _ in range(10):
        n = random.randint(1, MAX_N)
        alph = random.choice(['P', 'P-', 'NP', 'N-'])
        save_case(random_case(n, alph), 'random')
        
if __name__=='__main__':
    main()
