#!/usr/bin/python
# -*- coding: utf-8 -*-

# Copyright 2014 Marcus Sundman

# This program is free software; you can redistribute it and/or modify
# it under the terms of version 2 of the GNU General Public License as
# published by the Free Software Foundation.

"""A program replicating the functionality of id3lib's id3cp, using mutagen for
tag loading and saving.
"""

from __future__ import print_function

import sys
import os.path
from optparse import OptionParser
import mutagen
import mutagen.id3

VERSION = (0, 1)


def printerr(msg):
    print(msg, file=sys.stderr)


class ID3OptionParser(OptionParser):
    def __init__(self):
        mutagen_version = mutagen.version_string
        my_version = ".".join(map(str, VERSION))
        version = "mid3cp %s\nUses Mutagen %s" % (my_version, mutagen_version)
        self.disable_interspersed_args()
        OptionParser.__init__(
            self, version=version,
            usage="%prog [option(s)] <src> <dst>",
            description=("Copies ID3 tags from <src> to <dst>. Mutagen-based "
                         "replacement for id3lib's id3cp."))


def copy(src, dst, write_v1=True, excluded_tags=None, verbose=False):
    """Returns 0 on success"""

    if excluded_tags is None:
        excluded_tags = []

    try:
        id3 = mutagen.id3.ID3(src, translate=False)
    except mutagen.id3.ID3NoHeaderError:
        printerr("No ID3 header found in %s" % src)
        return 1
    except StandardError as err:
        print_(str(err))
        return 1
    else:
        if verbose:
            printerr("File %s contains:" % src)
            printerr(id3.pprint())

        for tag in excluded_tags:
            id3.delall(tag)

        # if the source is 2.3 save it as 2.3
        if id3.version < (2, 4, 0):
            id3.update_to_v23()
            v2_version = 3
        else:
            id3.update_to_v24()
            v2_version = 4

        try:
            id3.save(dst, v1=(2 if write_v1 else 0), v2_version=v2_version)
        except StandardError as err:
            printerr("Error saving %s:\n%s" % (dst, str(err)))
            return 1
        else:
            if verbose:
                printerr("Successfully saved %s" % dst)
            return 0


def main(argv):
    parser = ID3OptionParser()
    parser.add_option("-v", "--verbose", action="store_true", dest="verbose",
                      help="print out saved tags", default=False)
    parser.add_option("--write-v1", action="store_true", dest="write_v1",
                      default=False, help="write id3v1 tags")
    parser.add_option("-x", "--exclude-tag", metavar="TAG", action="append",
                      dest="x", help="exclude the specified tag", default=[])
    (options, args) = parser.parse_args(argv[1:])

    if len(args) != 2:
        parser.print_help(file=sys.stderr)
        return 1

    (src, dst) = args

    if not os.path.isfile(src):
        printerr("File not found: '%s'" % src)
        parser.print_help(file=sys.stderr)
        return 1

    if not os.path.isfile(dst):
        printerr("File not found: '%s'" % dst)
        parser.print_help(file=sys.stderr)
        return 1

    if os.path.samefile(src, dst):
        printerr("Source and destination files are the same!")
        parser.print_help(file=sys.stderr)
        return 1

    # Strip tags - "-x FOO" adds whitespace at the beginning of the tag name
    excluded_tags = [x.strip() for x in options.x]

    return copy(src, dst, options.write_v1, excluded_tags, options.verbose)


if __name__ == "__main__":
    sys.exit(main(sys.argv))
