#!/usr/bin/python3
import unittest
import subprocess

import PyPDF2


def getNumPages(pdf_path):
    with open(pdf_path, 'rb') as pdf_file:
        read_pdf = PyPDF2.PdfFileReader(pdf_file)
        num_pages = read_pdf.getNumPages()
    return num_pages


def getContents(pdf_path, num_pages):
    contents = {}
    for i in range(1, num_pages+1):
        page_text = subprocess.check_output(
            ["pdftotext", "-f", str(i), "-l", str(i), pdf_path, "-"])
        page_text.strip()
        contents[i] = []
        for line in page_text.splitlines():
            line.strip()
            if line:
                try:
                    contents[i].append(int(line))
                except ValueError:
                    pass
    return contents


def convertToBooklet(in_pdf, out_pdf):
    subprocess.check_call(
        ['bin/bookletimposer', '-a', '-b', '-o', out_pdf,
         in_pdf])


def convertToLinear(in_pdf, out_pdf):
    subprocess.check_call(
        ['bin/bookletimposer', '-a', '-l', '-o', out_pdf,
         in_pdf])


def convertScale(in_pdf, out_pdf):
    subprocess.check_call(
        ['bin/bookletimposer', '-a', '-l', '-o', out_pdf,
         in_pdf])


class testBookletimposerCli(unittest.TestCase):
    def testBookletize8p(self):
        print("\nConverting 8p to booklet")
        out_path = '/tmp/test-8p-bookelt.pdf'
        expected = {1: [8, 1],
                    2: [2, 7],
                    3: [6, 3],
                    4: [4, 5]}

        convertToBooklet('tests/test-8p.pdf', out_path)

        # check the number of pages
        num_pages = getNumPages(out_path)
        self.assertEqual(num_pages, 4)

        # check that the pages are in the right order
        contents = getContents(out_path, num_pages)
        self.assertDictEqual(contents, expected)

    def testBookletize5p(self):
        print("\nConverting 5p to booklet")
        out_path = '/tmp/test-5p-booklet.pdf'
        expected = {1: [1],
                    2: [2],
                    3: [3],
                    4: [4, 5]}

        convertToBooklet('tests/test-5p.pdf', out_path)

        # check the number of pages
        num_pages = getNumPages(out_path)
        self.assertEqual(num_pages, 4)

        # check that the pages are in the right order
        contents = getContents(out_path, num_pages)
        self.assertDictEqual(contents, expected)

    def testBookletize3p(self):
        print("\nConverting 3p to booklet")
        out_path = '/tmp/test-3p-booklet.pdf'
        expected = {1: [1],
                    2: [2, 3]}

        convertToBooklet('tests/test-3p.pdf', out_path)

        # check the number of pages
        num_pages = getNumPages(out_path)
        self.assertEqual(num_pages, 2)

        # check that the pages are in the right order
        contents = getContents(out_path, num_pages)
        self.assertDictEqual(contents, expected)


    def testLinearize8p(self):
        print("\nConverting 8p to linear")
        out_path = '/tmp/test-8p-linear.pdf'
        expected = {1: [1],
                    2: [2],
                    3: [3],
                    4: [4],
                    5: [5],
                    6: [6],
                    7: [7],
                    8: [8]}

        convertToLinear('tests/test-8p-booklet.pdf', out_path)

        # check the number of pages
        num_pages = getNumPages(out_path)
        self.assertEqual(num_pages, 8)

        # check that the pages are in the right order
        contents = getContents(out_path, num_pages)
        self.assertDictEqual(contents, expected)

    def testScale8p(self):
        print("\nScaing 8p")
        out_path = '/tmp/test-8p-bookelt.pdf'
        expected = {1: [8, 1],
                    2: [2, 7],
                    3: [6, 3],
                    4: [4, 5]}

        convertToBooklet('tests/test-8p.pdf', out_path)

        # check the number of pages
        num_pages = getNumPages(out_path)
        self.assertEqual(num_pages, 4)

        # check that the pages are in the right order
        contents = getContents(out_path, num_pages)
        self.assertDictEqual(contents, expected)


if __name__ == '__main__':
    unittest.main()
