#!/usr/bin/env python
# encoding: utf-8

# pylint: skip-file

import unittest

from _diff import diff, guess_edit
from position import Position


def transform(a, cmds):
    buf = a.split("\n")

    for cmd in cmds:
        ctype, line, col, char = cmd
        if ctype == "D":
            if char != '\n':
                buf[line] = buf[line][:col] + buf[line][col+len(char):]
            else:
                buf[line] = buf[line] + buf[line+1]
                del buf[line+1]
        elif ctype == "I":
            buf[line] = buf[line][:col] + char + buf[line][col:]
        buf = '\n'.join(buf).split('\n')
    return '\n'.join(buf)


import unittest

# Test Guessing  {{{
class _BaseGuessing(object):
    def runTest(self):
        rv, es = guess_edit(self.initial_line, self.a, self.b, Position(*self.ppos), Position(*self.pos))
        self.assertEqual(rv, True)
        self.assertEqual(self.wanted, es)

class TestGuessing_Noop0(_BaseGuessing, unittest.TestCase):
    a, b = [], []
    initial_line = 0
    ppos, pos = (0, 6), (0, 7)
    wanted = ()

class TestGuessing_InsertOneChar(_BaseGuessing, unittest.TestCase):
    a, b = ["Hello  World"], ["Hello   World"]
    initial_line = 0
    ppos, pos = (0, 6), (0, 7)
    wanted = (
        ("I", 0, 6, " "),
    )
class TestGuessing_InsertOneChar1(_BaseGuessing, unittest.TestCase):
    a, b = ["Hello  World"], ["Hello   World"]
    initial_line = 0
    ppos, pos = (0, 7), (0, 8)
    wanted = (
        ("I", 0, 7, " "),
    )
class TestGuessing_BackspaceOneChar(_BaseGuessing, unittest.TestCase):
    a, b = ["Hello  World"], ["Hello World"]
    initial_line = 0
    ppos, pos = (0, 7), (0, 6)
    wanted = (
        ("D", 0, 6, " "),
    )
class TestGuessing_DeleteOneChar(_BaseGuessing, unittest.TestCase):
    a, b = ["Hello  World"], ["Hello World"]
    initial_line = 0
    ppos, pos = (0, 5), (0, 5)
    wanted = (
        ("D", 0, 5, " "),
    )

# End: Test Guessing  }}}

class _Base(object):
    def runTest(self):
        es = diff(self.a, self.b)
        tr = transform(self.a, es)
        self.assertEqual(self.b, tr)
        self.assertEqual(self.wanted, es)

class TestEmptyString(_Base, unittest.TestCase):
    a, b = "", ""
    wanted = ()

class TestAllMatch(_Base, unittest.TestCase):
    a, b = "abcdef", "abcdef"
    wanted = ()

class TestLotsaNewlines(_Base, unittest.TestCase):
    a, b = "Hello", "Hello\nWorld\nWorld\nWorld"
    wanted = (
        ("I", 0, 5, "\n"),
        ("I", 1, 0, "World"),
        ("I", 1, 5, "\n"),
        ("I", 2, 0, "World"),
        ("I", 2, 5, "\n"),
        ("I", 3, 0, "World"),
    )

class TestCrash(_Base, unittest.TestCase):
    a = 'hallo Blah mitte=sdfdsfsd\nhallo kjsdhfjksdhfkjhsdfkh mittekjshdkfhkhsdfdsf'
    b = 'hallo Blah mitte=sdfdsfsd\nhallo b mittekjshdkfhkhsdfdsf'
    wanted = (
        ("D", 1, 6, "kjsdhfjksdhfkjhsdfkh"),
        ("I", 1, 6, "b"),
    )

class TestRealLife(_Base, unittest.TestCase):
    a = 'hallo End Beginning'
    b = 'hallo End t'
    wanted = (
        ("D", 0, 10, "Beginning"),
        ("I", 0, 10, "t"),
    )

class TestRealLife1(_Base, unittest.TestCase):
    a = 'Vorne hallo Hinten'
    b = 'Vorne hallo  Hinten'
    wanted = (
        ("I", 0, 11, " "),
    )

class TestWithNewline(_Base, unittest.TestCase):
    a = 'First Line\nSecond Line'
    b = 'n'
    wanted = (
        ("D", 0, 0, "First Line"),
        ("D", 0, 0, "\n"),
        ("D", 0, 0, "Second Line"),
        ("I", 0, 0, "n"),
    )


class TestCheapDelete(_Base, unittest.TestCase):
    a = 'Vorne hallo Hinten'
    b = 'Vorne Hinten'
    wanted = (
        ("D", 0, 5, " hallo"),
    )

class TestNoSubstring(_Base, unittest.TestCase):
    a,b = "abc", "def"
    wanted = (
        ("D", 0, 0, "abc"),
        ("I", 0, 0, "def"),
    )

class TestCommonCharacters(_Base, unittest.TestCase):
    a,b = "hasomelongertextbl", "hol"
    wanted = (
        ("D", 0, 1, "asomelongertextb"),
        ("I", 0, 1, "o"),
    )

class TestUltiSnipsProblem(_Base, unittest.TestCase):
    a = "this is it this is it this is it"
    b = "this is it a this is it"
    wanted = (
        ("D", 0, 11, "this is it"),
        ("I", 0, 11, "a"),
    )

class MatchIsTooCheap(_Base, unittest.TestCase):
    a = "stdin.h"
    b = "s"
    wanted = (
        ("D", 0, 1, "tdin.h"),
    )

class MultiLine(_Base, unittest.TestCase):
    a = "hi first line\nsecond line first line\nsecond line world"
    b = "hi first line\nsecond line k world"

    wanted = (
        ("D", 1, 12, "first line"),
        ("D", 1, 12, "\n"),
        ("D", 1, 12, "second line"),
        ("I", 1, 12, "k"),
    )


if __name__ == '__main__':
   unittest.main()
   # k = TestEditScript()
   # unittest.TextTestRunner().run(k)
