#!/usr/bin/env/ python

#    Copyright (C) 2021, Anais Berck
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.

#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details: <http://www.gnu.org/licenses/>.

from flask import Flask, render_template, request, Response, session
# from weasyprint import HTML
from pagedjs import make_pdf
from settings import DEBUG, BASEURL, DEFAULT_LANGUAGE, SECRET_KEY

import textwrap

import os
from fcntl import lockf, LOCK_EX, LOCK_UN

# Spacy tries to import CUDA, do not break when it fails
try:
  from paseo import crear_camino
except ModuleNotFoundError:
  pass

import os.path

basepath = os.path.dirname(__file__)

app = Flask(__name__)
app.secret_key = SECRET_KEY

# Book HTML is loaded through filesystem, in a tmp dir, make path absolute.
PAGEDJS_STATIC_DIR = os.path.join(basepath, 'static')

COUNTER_PATH_ES = 'edition_counter.txt'
COUNTER_PATH_EN = 'edition_counter_en.txt'

def get_edition_count_es():
  fd = os.open(COUNTER_PATH_ES, os.O_RDWR|os.O_CREAT)
  lockf(fd, LOCK_EX)
  fo = os.fdopen(fd, 'r+', encoding='utf-8')
  content = fo.read()
  if not content:
    edition_count = 0
  else:
    edition_count = int(content.strip())
  edition_count += 1
  fo.seek(0)
  fo.truncate()
  fo.write(str(edition_count))
  fo.flush()
  lockf(fd, LOCK_UN)
  os.close(fd)

  return edition_count

def get_edition_count_en():
  fd = os.open(COUNTER_PATH_EN, os.O_RDWR|os.O_CREAT)
  lockf(fd, LOCK_EX)
  fo = os.fdopen(fd, 'r+', encoding='utf-8')
  content = fo.read()
  if not content:
    edition_count = 0
  else:
    edition_count = int(content.strip())
  edition_count += 1
  fo.seek(0)
  fo.truncate()
  fo.write(str(edition_count))
  fo.flush()
  lockf(fd, LOCK_UN)
  os.close(fd)

  return edition_count

def wrap (text, width):
  return'\n'.join(['\n'.join(textwrap.wrap(line, width=width)) for line in text.splitlines()])

def read_sources (*paths):
  return [ (p, wrap(open(p, 'r').read(), 105)) for p in paths ]

def get_language():
  if 'LANGUAGE' in session:
    return session['LANGUAGE']
  else:
    return DEFAULT_LANGUAGE

def set_language(language):
  session['LANGUAGE'] = language
  session.modified = True

def index_es():
  context = {
    BASEURL: BASEURL
  }
  return render_template('index.html', **context)

def index_en():
  context = {
    BASEURL: BASEURL
  }
  return render_template('index_en.html', **context)

"""
  Adds the last word of the previous step to the itinerary
"""
def add_last_word_previous_step (itinerary):
  new_itinerary = []
  last_word_previous_step = None

  for step in itinerary:
    new_itinerary.append(
      (
        step[0],
        step[1],
        step[2],
        step[3],
        last_word_previous_step
      )
    )

    last_word_previous_step = step[3][-1][0]

  return new_itinerary

@app.route('{}/en'.format(BASEURL))
def en():
  set_language('en')
  return index()
  
@app.route('{}/es'.format(BASEURL))
def es():
  set_language('es')
  return index()

@app.route('{}/'.format(BASEURL))
def index():
  if get_language() == 'es':
    return index_es()
  else:
    return index_en()

def book_es ():
  edition_count = get_edition_count_es()

  fragment = max(0, min(1, int(request.form['fragment'])))  

  first_word = 'un'

  if fragment == 0:
    novel = os.path.join(basepath, '../data/emilia_prueba.txt')
    author = 'Emilia Pardo Bazán' # Non breaking spaces
    title = 'La Madre Naturaleza' # Non breaking spaces
  else:
    novel = os.path.join(basepath, '../data/prueba.txt')
    author = 'Benito Pérez Gáldos' # Non breaking spaces
    title = 'Miau'

  path = add_last_word_previous_step(crear_camino(novel, first_word, 'es'))
  complete_sentence = path[-1][1] + path[-1][0]

  context = { 
    'title': title, 
    'author': author, 
    'path': path, 
    'STATIC_DIR': '/static' if DEBUG else PAGEDJS_STATIC_DIR,
    'DEBUG': DEBUG,
    'edition_count': edition_count,
    'sources': read_sources('paseo.py', 'medialab.py'),
    'complete_sentence': complete_sentence,
  }
  
  html = render_template('book.html', **context)
  
  if (DEBUG):
    return html
  else:
    pdf = make_pdf(html)

    r = Response(pdf, mimetype='application/pdf')

    r.headers.extend({
      'Content-Disposition': 'attachment; filename="Paseo por arboles de Madrid.pdf"'
    })

    return r

def book_en ():
  edition_count = get_edition_count_en()
  
  fragment = max(0, min(1, int(request.form['fragment'])))  

  first_word = 'a'

  if fragment == 0:
    novel = os.path.join(basepath, '../data/emilia_english.txt')
    author = 'Emilia Pardo Bazán' # Non breaking spaces
    title = 'The Swan of Vila Morta' # Non breaking spaces
  else:
    novel = os.path.join(basepath, '../data/benito_english.txt')
    author = 'Benito Pérez Gáldos' # Non breaking spaces
    title = 'Marianela'

  path = add_last_word_previous_step(crear_camino(novel, first_word, 'en'))
  complete_sentence = path[-1][1] + path[-1][0]

  context = { 
    'title': title, 
    'author': author, 
    'path': path, 
    'STATIC_DIR': '/static' if DEBUG else PAGEDJS_STATIC_DIR,
    'DEBUG': DEBUG,
    'edition_count': edition_count,
    'sources': read_sources('paseo.py', 'medialab.py'),
    'complete_sentence': complete_sentence,
  }
  
  html = render_template('book_en.html', **context)
  
  if (DEBUG):
    return html
  else:
    pdf = make_pdf(html)

    r = Response(pdf, mimetype='application/pdf')

    r.headers.extend({
      'Content-Disposition': 'attachment; filename="Walk along the trees of Madrid.pdf"'
    })

    return r
@app.route('{}/book'.format(BASEURL), methods=['POST'])
def book():
  if get_language() == 'es':
    return book_es()
  else:
    return book_en()
