#==============================================================================
# Copyright (C) 2011 by Loïc Grobol
#
# This file is part of CTESLO.
# 
#    CTESLO 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.
# 
#    CTESLO 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.
# 
#    You should have received a copy of the GNU General Public License
#    along with CTESLO.  If not, see <http://www.gnu.org/licenses/>.
#==============================================================================

"""
Created on 20 juin 2011

@author: Loïc Grobol <loic.grobol@gmail.com>

Bundle for all external tools handling matters.
"""

from os.path import dirname as pdir
import os, subprocess, tempfile, sys
from libcteslo.tasks.utils import copy, temporary_files_collection
from libcteslo.dflib import tokenization as dft, columns_handling as dfch

ROOT = sys.path[0]
DIR = "external_tools"
PATH = os.path.join(ROOT, DIR)
HELPER_NAME = "tool.py"
TOOL_OUTPUT_NAME = "out"

def _execute_tool(tool, input_file) -> "output file's absolute path":
    """Apply a tool to a file, output in a <tool>/ directory sibling
    to the input file and return the path of the output file."""
    tool_path = os.path.join(PATH, tool)
    helper_path = os.path.join(tool_path, HELPER_NAME)
    file_path = os.path.abspath(input_file)

    out_file = os.path.join(os.path.dirname(file_path), tool, TOOL_OUTPUT_NAME)
    try:
        os.mkdir(pdir(out_file))
    except OSError:
        pass

    subprocess.call(" ".join([helper_path, "-i", file_path, "-o", out_file]), shell=True)

    return out_file

def execute_tool(tool, input_file):
    """Apply a tool or a list of tools to a file, return the list of
    the output files."""
    if isinstance(tool, str):
        tool = [tool]
    result = []
    for t in tool:
        result.append(_execute_tool(t, input_file))
    return result


def apply_external_tools(in_stream, out_stream, tools):
    with tempfile.TemporaryDirectory(prefix=".cteslo_") as temp:
        in_file = os.path.join(temp, "in")
        t = temporary_files_collection(in_file)
        # Output the input stream content inside a temp file
        copy(in_stream, in_file)
        # Tokenize the temp file
        dft.stream_tokenize(in_file, t.final, bio=False)
        # apply external tools
        external_tooled = execute_tool(tools, in_file)
        # add external tools'data to taggable
        for file in external_tooled:
            dft.stream_tokenize(file, t.tokenized)
            dfch.stream_delete(t.tokenized, t.appendable, [0])
            dfch.stream_insert(t.appendable, t.final, t.buffer)
            copy(t.buffer, t.final)

        dfch.stream_delete(t.final, out_stream, [0])
