#!/usr/bin/env python3
"""
mdiff - Multiple Document Type Diff

mdiff is a program designed to compare several types of files.
mdiff can compare standard text files, open office documents,
latex documents and config files documents.

This module is implemented by the main function.
Function main: parses arguments and calls requested functions.
"""

#import optparse, sys, time, os, difflib, mimetypes, fileinfo
import optparse, sys, mimetypes, textdiff, fileinfo, configdiff, latexdiff, oodiff


def main():

    #usage for help
    usage = "usage: %prog [options] from_file to_file"
    version="%prog 1.0"
    description="""Multiple Document Type Diff, compares various types of files."""

    #standard diff options
    parser = optparse.OptionParser(usage=usage, version=version, description=description)

    #groups
    group_text = optparse.OptionGroup(parser, "Text differencing tools")
    group_other_files = optparse.OptionGroup(parser, "Other files differencing tools")
    group_text_options = optparse.OptionGroup(parser, "Advanced options for text differencing tools")

    #text diff options
    group_text.add_option("-d","--standard-diff",action="store_true", default=False, help='Use of standard GNU diff output format.')
    group_text.add_option("-n","--normal-diff",  action="store_true", default=False, help='Use of ndiff output format.')
    group_text.add_option("-c","--context-diff", action="store_true", default=False, help='Use of the context output format.')
    group_text.add_option("-C","--context",metavar="lines",action="store", type="int", default=3, help='Set, number of context lines. Default is three. Use of this option with option -c')
    group_text.add_option("-u","--unified-diff", action="store_true", default=False, help='Use of the unified output format.')
    group_text.add_option("-v","--html-diff",    action="store_true", default=False, help='Produces HTML side by side diff (can use -c and -C in conjunction)')
    parser.add_option_group(group_text)


    #other files diff options
    group_other_files.add_option("-f","--file-info",    action="store_true", default=False, help='Compares file informations. Shows only different attributes')
    group_other_files.add_option("-F",                  action="store_true", default=False, help='Compares file informations. Shows all attributes')
    group_other_files.add_option("-o","--open-office",  action="store_true", default=False, help='Compares Open Office Text files.')
    group_other_files.add_option("-O","--line-width",   action="store",metavar="characters", type="int", default=78, help='Width of lines in comparation Open Office files.')
    #~ parser.add_option("-x","--xml",          action="store_true", default=False, help='Compare xml files.')
    group_other_files.add_option("-l","--latex",        action="store_true", default=False, help='Compares latex files.')
    group_other_files.add_option("-k","--config-files", action="store_true", default=False, help='Compares config files.')
    #~ parser.add_option("-p","--pictures",     action="store_true", default=False, help='Compare pictures.')
    parser.add_option_group(group_other_files)

    #text diff advanced options
    group_text_options.add_option("-i","--ignore-case",         action="store_true", default=False, help='Ignores case differences in file contents.')
    group_text_options.add_option("-b","--ignore-space-change", action="store_true", default=False, help='Ignores changes in the amount of white space.')
    group_text_options.add_option("-w","--ignore-all-space",    action="store_true", default=False, help='Ignores all white spaces, but blank lines are deleted and then texts are compared. Indices doesn\'t have to be correct. It is recommended to use the ndiff output format.')
    group_text_options.add_option("-B","--ignore-blank-lines",  action="store_true", default=False, help='Ignores changes whose lines are all blank. Blank lines are deleted and then texts are compared. Indices doesn\'t have to be correct. It is recommended to use the ndiff output format.')
    group_text_options.add_option("-I","--ignore-matching-lines",metavar="RE",   action="store", type="string", default='' , help='Ignores changes whose lines all match RE. Matching lines are deleted and then compared. Indices doesn\'t have to be correct. It is recommended to use the ndiff output format.')
    group_text_options.add_option("-J","--ignore-matching-words",metavar="RE",   action="store", type="string", default='' , help='Ignores changes whose words all match RE.')
    parser.add_option_group(group_text_options)

    #parse arguments
    (options, args) = parser.parse_args()

    if len(args) != 2:
        parser.print_help()
        sys.exit(1)

    file1_name, file2_name = args
    #according to parameters are called functions
    if options.file_info or options.F:
        sys.stdout.writelines(fileinfo.FileInfo(file1_name, file2_name, options).compare_fileinfo())

    elif options.config_files:
        sys.stdout.writelines(configdiff.ConfigDiff(file1_name, file2_name, options).config_diff())

    elif options.latex:
        sys.stdout.writelines(latexdiff.TexDiff(file1_name, file2_name, options).compare())

    elif options.open_office:
        sys.stdout.writelines(oodiff.OODiff(file1_name, file2_name, options).compare())

    elif options.normal_diff:
        sys.stdout.writelines(textdiff.TextDiff(file1_name,file2_name,options).normal_diff())

    elif options.context_diff:
        sys.stdout.writelines(textdiff.TextDiff(file1_name,file2_name,options).context_diff())

    elif options.unified_diff:
        sys.stdout.writelines(textdiff.TextDiff(file1_name,file2_name,options).unified_diff())

    elif options.html_diff:
        sys.stdout.writelines(textdiff.TextDiff(file1_name,file2_name,options).html_diff())

    elif options.standard_diff:
        sys.stdout.writelines(textdiff.TextDiff(file1_name,file2_name,options).gnu_diff())

    #it could find some types of files by mime types
    else:
        mimetypes.init()
        if mimetypes.guess_type(file1_name,False)[0] == 'application/vnd.oasis.opendocument.text':
            sys.stdout.writelines(oodiff.OODiff(file1_name, file2_name, options).compare())
        elif mimetypes.guess_type(file1_name)[0] == 'text/x-tex':
            sys.stdout.writelines(latexdiff.TexDiff(file1_name, file2_name, options).compare())
        else:
            sys.stdout.writelines(textdiff.TextDiff(file1_name,file2_name,options).gnu_diff())

    return 0


if __name__ == '__main__':
    main()
