from snipper.fix_s import get_s
from snipper.block_parsing import block_split
import textwrap
import numpy as np  #!s

# Implement a sieve here.
def primes_sieve(limit):
    limitn = limit+1 #!b
    primes = range(2, limitn)

    for i in primes:
        factors = list(range(i, limitn, i))
        for f in factors[1:]:
            if f in primes:
                primes.remove(f)
    return primes #!b

# Example use: print(primes_sieve(42)) #!s

def wspace(l):
    whitespace = " " * (len(l) - len(l.lstrip()))
    return whitespace

def cmnt(lines):
    whitespace = " " * (len(lines[0]) - len(lines[0].lstrip()))
    lines = textwrap.dedent("\n".join(lines)).splitlines()
    lines = ["# " + l for l in lines]
    return lines, whitespace

def obscure(blk, fun, outfile):
    blok = block_split(blk, "#!b")
    lines2 = blok['first'] + fun(blok['block']) + blok['last']
    lines2.append(  wspace(lines2[-1] ) + "raise NotImplementedError('Complete the above program')" )
    s = '\n'.join(lines2)
    with open(outfile, 'w') as f:
        f.write(s)
    return s

# driver program
if __name__ == '__main__':
    # Read the code using the #!s-block-tag.
    with open(__file__, 'r') as f:
        s = f.read().splitlines()
    blk = get_s(s)['']

    # Save it in output for the readme.
    with open("cs101_output/sieve.py", 'w') as f:
        f.write('\n'.join(blk))

    # Example 1: Simply permute the lines
    def f1(lines):
        lines, whitespace = cmnt(lines)
        lines = [lines[i] for i in np.random.permutation(len(lines))]
        lines = textwrap.indent("\n".join(lines), whitespace).splitlines()
        return lines
    obscure(blk, f1, 'cs101_output/obscure_1.py')

    # Example 2: Try to preserve keywords and special syntax symbols
    def f2(lines):
        lines, whitespace = cmnt(lines)
        kp = """#'"[](){},.+-012345679:="""
        l2 = []
        for line in lines:
            line2 = []
            for w in line.split(' '):
                if w in ['', 'return', 'if', 'else' '=', '#', "for", "in"]:
                    line2.append(w)
                else:
                    w2 = "".join( [ (t if t in kp else '?') for t in w] )
                    line2.append(w2)
            l2.append(" ".join(line2))
        lines = l2
        lines = textwrap.indent("\n".join(lines), whitespace).splitlines()
        return lines
    obscure(blk, f2, 'cs101_output/obscure_2.py')

    # Example 3: keep half of the lines
    def f3(lines):
        lines = [ (l.strip(), len(l.strip()), wspace(l)) for l in lines ]
        lines = [ wp + l[:k//2] + "?"*(k-k//2) for l, k, wp in lines]
        lines, whitespace = cmnt(lines)
        lines = textwrap.indent("\n".join(lines), whitespace).splitlines()
        return lines
    obscure(blk, f3, 'cs101_output/obscure_3.py')