import subprocess
from io import BytesIO
from tempfile import NamedTemporaryFile
from typing import List, Tuple, BinaryIO

from PyPDF4 import PdfFileReader, PdfFileWriter
from telegram import InlineKeyboardMarkup, InlineKeyboardButton

from .page_selection import PageSelection


def get_inline_keyboard(layout: List[List[Tuple[str, str]]]) -> InlineKeyboardMarkup:
    '''Return an inline keyboard from a layout of buttons
       specified as a tuple of the text and callback data.'''
    if layout is None:
        return None

    return InlineKeyboardMarkup([
        [InlineKeyboardButton(name, callback_data=data) for (name, data) in row]
        for row in layout if row
    ])


# pylint: disable=invalid-name

def s(amount: int, plural_ending: str = 's', singular_ending: str = '') -> str:
    '''Return the plural or singular ending depending on the amount.'''
    if amount == 1:
        return singular_ending
    return plural_ending

# pylint: enable=invalid-name


def convert_to_pdf(file: NamedTemporaryFile, mime: str) -> bool:
    '''Convert a file to PDF if necessary.
       Return whether the conversion took place.'''
    if mime == 'application/pdf':
        return False

    unoconv = subprocess.run(['unoconv', '--stdout', '-f', 'pdf', file.name],
                             text=False,
                             capture_output=True,
                             timeout=60,
                             check=True)
    file.seek(0)
    file.write(unoconv.stdout)
    file.truncate()

    return True


def is_portrait(reader: PdfFileReader) -> bool:
    '''Based on the existing PDF reader, determine the orientation of the document.'''
    landscape_pages = 0
    portrait_pages = 0
    for page in reader.pages:
        rotation = page.get('/Rotate')
        width = page.mediaBox.getWidth()
        height = page.mediaBox.getHeight()
        if (width > height) == (rotation in (0, 180, None)):
            landscape_pages += 1
        else:
            portrait_pages += 1

    return portrait_pages > landscape_pages


def apply_page_selection(pdf: BinaryIO, pages: PageSelection):
    '''Exclude the pages from the PDF that weren't selected.'''
    reader = PdfFileReader(pdf)
    writer = PdfFileWriter()

    for page_idx in pages:
        writer.addPage(reader.getPage(page_idx))

    output = BytesIO()
    writer.write(output)
    pdf.seek(0)
    pdf.write(output.getvalue())
    pdf.truncate()
    pdf.seek(0)

import subprocess
from io import BytesIO
from tempfile import NamedTemporaryFile
from typing import List, Tuple, BinaryIO

from PyPDF4 import PdfFileReader, PdfFileWriter
from telegram import InlineKeyboardMarkup, InlineKeyboardButton

from .page_selection import PageSelection


def get_inline_keyboard(layout: List[List[Tuple[str, str]]]) -> InlineKeyboardMarkup:
    '''Return an inline keyboard from a layout of buttons
       specified as a tuple of the text and callback data.'''
    if layout is None:
        return None

    return InlineKeyboardMarkup([
        [InlineKeyboardButton(name, callback_data=data) for (name, data) in row]
        for row in layout if row
    ])


# pylint: disable=invalid-name

def s(amount: int, plural_ending: str = 's', singular_ending: str = '') -> str:
    '''Return the plural or singular ending depending on the amount.'''
    if amount == 1:
        return singular_ending
    return plural_ending

# pylint: enable=invalid-name


def convert_to_pdf(file: NamedTemporaryFile, mime: str) -> bool:
    '''Convert a file to PDF if necessary.
       Return whether the conversion took place.'''
    if mime == 'application/pdf':
        return False

    unoconv = subprocess.run(['unoconv', '--stdout', '-f', 'pdf', file.name],
                             text=False,
                             capture_output=True,
                             timeout=60,
                             check=True)
    file.seek(0)
    file.write(unoconv.stdout)
    file.truncate()

    return True


def is_portrait(reader: PdfFileReader) -> bool:
    '''Based on the existing PDF reader, determine the orientation of the document.'''
    landscape_pages = 0
    portrait_pages = 0
    for page in reader.pages:
        rotation = page.get('/Rotate')
        width = page.mediaBox.getWidth()
        height = page.mediaBox.getHeight()
        if (width > height) == (rotation in (0, 180, None)):
            landscape_pages += 1
        else:
            portrait_pages += 1

    return portrait_pages > landscape_pages


def apply_page_selection(pdf: BinaryIO, pages: PageSelection):
    '''Exclude the pages from the PDF that weren't selected.'''
    reader = PdfFileReader(pdf)
    writer = PdfFileWriter()

    for page_idx in pages:
        writer.addPage(reader.getPage(page_idx))

    output = BytesIO()
    writer.write(output)
    pdf.seek(0)
    pdf.write(output.getvalue())
    pdf.truncate()
    pdf.seek(0)

Return an inline keyboard from a layout of buttons        specified as a tuple of the text and callback data. # pylint: disable=invalid-name Return the plural or singular ending depending on the amount. # pylint: enable=invalid-name Convert a file to PDF if necessary.        Return whether the conversion took place. Based on the existing PDF reader, determine the orientation of the document. Exclude the pages from the PDF that weren't selected.