#! /usr/bin/env python3
#
#
# Advene: Annotate Digital Videos, Exchange on the NEt
# Copyright (C) 2019 Olivier Aubert <contact@olivieraubert.net>
#
# This file is part of Advene.
#
# Advene 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 2 of the License, or
# (at your option) any later version.
#
# Advene 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 Foobar; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
#

import logging
logger = logging.getLogger(__name__)

"""Convert annotation ids to uuids
"""
import shutil
import sys
import uuid
import xml.etree.ElementTree as ET
from xml.etree.ElementTree import parse, QName
import zipfile

# Deal directly with storage format

# Namespace handling
ns='http://experience.univ-lyon1.fr/advene/ns'
ET._namespace_map[ns]=''
ET._namespace_map['http://purl.org/dc/elements/1.1/']='dc'
ET._namespace_map['http://experience.univ-lyon1.fr/advene/ns/advenetool']='advenetool'
ET._namespace_map["http://www.w3.org/1999/xlink"] = 'xlink'

HREF = '{http://www.w3.org/1999/xlink}href'

def tag(name, shortname=None):
    """Return the namespaced tag.
    """
    return '{%s}%s' % (ns, name)

# Hack into elementtree to generate a readable (namespace-prefix-wise)
# Advene package
def my_fixtag(tag, namespaces):
    # given a decorated tag (of the form {uri}tag), return prefixed
    # tag and namespace declaration, if any
    if isinstance(tag, QName):
        tag = tag.text
    namespace_uri, tag = str(tag[1:]).split("}", 1)
    prefix = namespaces.get(namespace_uri)
    if prefix is None:
        prefix = ET._namespace_map.get(namespace_uri)
        if prefix is None:
            prefix = "ns%d" % len(namespaces)
        namespaces[namespace_uri] = prefix
        if prefix == "xml":
            xmlns = None
        elif prefix == '':
            # Empty prefix from _namespace_map, assume it is the
            # default
            xmlns = ('xmlns', namespace_uri)
        else:
            xmlns = ("xmlns:%s" % prefix, namespace_uri)
    else:
        xmlns = None
    if prefix == '':
        return tag, xmlns
    else:
        return "%s:%s" % (prefix, tag), xmlns

# Hook into elementtree
ET.fixtag = my_fixtag

if __name__ == '__main__':
    logging.basicConfig(level=logging.DEBUG)
    SYNTAX = "%s original.azp destination.azp" % sys.argv[0]
    try:
        source_file = sys.argv[1]
        dest_file = sys.argv[2]
    except IndexError:
        logger.error(SYNTAX)
        sys.exit(1)

    # Copy source to destination
    shutil.copy(source_file, dest_file)

    # Read from dest_file
    with zipfile.ZipFile(source_file, 'r') as z:
        # Parse content.xml
        tree = parse(z.open('content.xml', 'r'))

    root = tree.getroot()

    mapping = {}
    for a in root.find(tag('annotations')).findall(tag('annotation')):
        ident = mapping[a.attrib['id']] = str(uuid.uuid1())
        a.attrib['id'] = ident

    # Fix relations
    for r in root.find(tag('annotations')).findall(tag('relation')):
        ident = mapping[r.attrib['id']] = str(uuid.uuid1())
        r.attrib['id'] = ident
        for m in r.find(tag('members')).findall(tag('member')):
            aid = m.attrib[HREF].lstrip('#')
            m.attrib[HREF] = '#' + mapping[aid]

    # write to dest_file
    with zipfile.ZipFile(source_file, 'r') as zin:
        with zipfile.ZipFile(dest_file, 'w', compression=zipfile.ZIP_DEFLATED) as zout:
            # Dump content.xml
            with zout.open('content.xml', 'w') as f:
                tree.write(f, encoding='utf-8')
            # Copy all other files
            for item in zin.infolist():
                if item.filename != 'content.xml':
                    buf = zin.read(item.filename)
                    zout.writestr(item, buf)
    logging.info("Converted ids from %s to %s", source_file, dest_file)
