#**************************************************************
#
#  Licensed to the Apache Software Foundation (ASF) under one
#  or more contributor license agreements.  See the NOTICE file
#  distributed with this work for additional information
#  regarding copyright ownership.  The ASF licenses this file
#  to you under the Apache License, Version 2.0 (the
#  "License"); you may not use this file except in compliance
#  with the License.  You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing,
#  software distributed under the License is distributed on an
#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
#  KIND, either express or implied.  See the License for the
#  specific language governing permissions and limitations
#  under the License.
#
#**************************************************************

from optparse import OptionParser
from sdf import SdfData
from pseudo import PseudoSet

import sys
import os
import shutil

class AbstractL10nTool:
    _options            = {}
    _args               = ""
    _resource_type      = ""
    _source_language    = "en-US"

    ##### Implement these abstract methods

    ##### Nameing scheme for the output files
    def get_outputfile_format_str(self):
        # filename,fileNoExt,language,extension,pathPrefix,pathPostFix,path
        #return "{path}/{fileNoExt}_{language}.{extension}"
        return self._options.pattern

    ################################# Merge single files ###########################################

    ##### Merge a single file
    def merge_file(self, inputfilename, outputfilename, parsed_file_ref, lang, is_forced_lang, sdfdata):
        pass

    ##### Helper for parse-once-use-often like parsing a xml file is needed implement it here
    def parse_file(self, filename):
        return None

    ################### Merge one big file containing all strings in all languages #################
    def merge_one_big_file(self, inputfile, outputfilename, parsed_file_ref, lang, sdfdata):
        pass

    ################### Extract a single File ######################################################
    def extract_file(self, inputfile):
        pass

    ################################################################################################

    def format_outputfile(self, filename, language):
        extension = filename[filename.rfind('.')+1:]
        file = filename[:filename.rfind('.')]
        # Python 2.3.x friendly
        return self.get_outputfile_format_str().replace('[', '%(').replace(']',')s') % \
                { 'filename': filename, 'fileNoExt': file, 'language': language, 'extension': extension, 'path_prefix': self._options.path_prefix,
                  'path_postfix': self._options.path_postfix, 'path': self.get_path() }

        #return self.get_outputfile_format_str().replace('[', '{').replace(']','}').format(
        #       filename=filename, fileNoExt=file, language=language, extension=extension, path_prefix=self._options.path_prefix,
        #       path_postfix=self._options.path_postfix, path=self.get_path())

    def get_path(self):
        if self._options.outputfile.find('/') == -1:
            return ""
        else:
            return self._options.outputfile[:self._options.outputfile.rfind('/')]

    def merge(self,  sdfdata):
        langset,forcedset, foundset = PseudoSet(), PseudoSet() , PseudoSet()

        if self._options.languages:
            langset = PseudoSet(self._options.languages)
        if self._options.forcedlanguages:
            forcedset = PseudoSet(self._options.forcedlanguages)
        if sdfdata.get_languages_found_in_sdf():
            foundset = sdfdata.get_languages_found_in_sdf()

        if self.has_multi_inputfiles():
            filelist = self.read_inputfile_list()
        else:
            filelist = self._options.inputfile

        for inputfile in filelist:
            ref = self.parse_file(inputfile)
            # Don't write that files if there is no l10n present
            if ((langset & foundset) - forcedset):  # all langs given and found in sdf without enforced
                [self.merge_file(inputfile,self.format_outputfile(inputfile, lang), ref, lang, False, sdfdata) for lang in ((langset & foundset) - forcedset)]
            # Always write those files even if there is no l10n available
            if forcedset: # all enforced langs
                [self.merge_file(inputfile, self.format_outputfile(inputfile, lang), ref, lang, True, sdfdata)  for lang in forcedset]
            # In case a big file have to be written
            if ((langset & foundset) | forcedset): # all langs given ,found in sdf and enforced ones
                self.merge_one_big_file(inputfile, self.format_outputfile(inputfile, lang), ref, ((langset & foundset) | forcedset), sdfdata)

    def has_multi_inputfiles(self):
        return self._options.inputfile[0] == '@'

    def copy_file(self, inputfilename, outputfilename):
        try:
            os.remove(outputfilename)
        except:
            pass

        try:
            os.remove(outputfilename)
        except:
            pass

        try:
            shutil.copy(inputfilename, outputfilename)
        except IOError:
            print("ERROR: Can not copy file '" + inputfilename + "' to " + "'" + outputfilename + "'")
            sys.exit(-1)

    def extract(self):
        try:
            f = open(self._options.outputfile, "w+")
            f.write(self.extract_file(self._options.inputfile))
        except IOError:
            print("ERROR: Can not write file " + self._options.outputfile)
        else:
            f.close()

    # Parse the common options
    def parse_options(self):
        parser = OptionParser()
        parser.add_option("-i", "--inputfile",       dest="inputfile",       metavar="FILE", help="resource file to read"         )
        parser.add_option("-o", "--outputfile",      dest="outputfile",      metavar="FILE", help="extracted sdf or merged file"  )
        parser.add_option("-m", "--inputsdffile",    dest="input_sdf_file",  metavar="FILE", help="merge this sdf file"           )
        parser.add_option("-x", "--pathprefix",      dest="path_prefix",     metavar="PATH", help=""                              )
        parser.add_option("-y", "--pathpostfix",     dest="path_postfix",    metavar="PATH", help=""                              )
        parser.add_option("-p", "--projectname",     dest="project_name",    metavar="NAME", help=""                              )
        parser.add_option("-r", "--projectroot",     dest="project_root",    metavar="PATH", help=""                              )
        parser.add_option("-f", "--forcedlanguages", dest="forcedlanguages", metavar="ISOCODE[,ISOCODE]", help="Always merge those langs even if no l10n is available for those langs" )
        parser.add_option("-l", "--languages",       dest="languages",       metavar="ISOCODE[,ISOCODE]", help="Merge those langs if l10n is found for each")
        parser.add_option("-s", "--pattern",         dest="pattern",         metavar="", help=""                                  )
        parser.add_option("-q", "--quiet",           action="store_true",    dest="quietmode", help="",default=False)
        (self._options, self.args) = parser.parse_args()

        # -l "de,pr,pt-BR" => [ "de" , "pt" , "pt-BR" ]
        parse_complex_arg = lambda arg: arg.split(",")

        if self._options.forcedlanguages:
            self._options.forcedlanguages = parse_complex_arg(self._options.forcedlanguages)
        if self._options.languages:
            self._options.languages = parse_complex_arg(self._options.languages)
        self.test_options()

    def __init__(self):
        self.parse_options()
        if self._options.input_sdf_file != None and len(self._options.input_sdf_file):
            sdfdata = SdfData(self._options.input_sdf_file)
            sdfdata.read()
            self.merge(sdfdata)
        else:
            self.extract()

    def make_dirs(self, filename):
        dir = filename[:filename.rfind('/')]
        if os.path.exists(dir):
            if os.path.isfile(dir):
                print("ERROR: There is a file '"+dir+"' where I want create a directory")
                sys.exit(-1)
            else:
                return
        else:
            try:
                os.makedirs(dir)
            except IOError:
                print("Error: Can not create dir " + dir)
                sys.exit(-1)

    def test_options(self):
        opt = self._options
        is_valid = lambda x: x != None and len(x) > 0
        return  is_valid(opt.project_root) and is_valid(opt.project_name) and is_valid(opt.languages) and \
                ( is_valid(opt.inputfile) and (( is_valid(opt.path_prefix) and is_valid(opt.path_postfix) ) or is_valid(opt.outputfile)) and \
                ( ( is_valid(opt.input_sdf_file) and ( is_valid(opt.outputfile) or  ( is_valid(opt.path_prefix) and is_valid(opt.path_postfix) ) or \
                ( is_valid(opt.inputfile) and is_valid(opt.outputFile)) ))))
        print("Strange options ...")
        sys.exit( -1 )

    def read_inputfile_list(self):
        if self.has_multi_inputfiles():
            lines = []
            try:
                f = open(self._options.inputfile[1:], "r")
                lines = [line.strip('\n') for line in f.readlines()]
            except IOError:
                print("ERROR: Can not read file list " + self._options.inputfile[2:])
                sys.exit(-1)
            else:
                f.close()
            return lines

    def get_filename_string(self, inputfile):
        absfile = os.path.realpath(os.path.abspath(inputfile))
        absroot = os.path.realpath(os.path.abspath(self._options.project_root))
        return absfile[len(absroot)+1:].replace('/','\\')
