#!/usr/bin/python -tt
# vim: ai ts=4 sts=4 et sw=4
#
# Copyright (C) 2010, 2011, 2012, 2013, 2014 Intel, Inc.
#
#    This program 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; version 2 of the License.
#
#    This program 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 this program; if not, write to the Free Software
#    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

"""A wrapper to handle with OBS operations"""

from __future__ import with_statement
import os
import shutil
from gitbuildsys.errors import ObsError

from common import buildservice
from common import runner
from common.utils import Workdir

from osc import core, oscerr

class ObsPackage(object):
    """ Wrapper class of local package dir of OBS
    """

    def __init__(self, basedir, prj, pkg, apiurl, apiuser, apipasswd):
        """Arguments:
          basedir: the base local dir to store obs packages
          prj: obs project
          pkg: obs package
          apiurl: the api url of obs service
          apiuser: the user of obs service
          apipasswd: the passwd of obs service user
        """

        self._bs = buildservice.BuildService(apiurl, apiuser, apipasswd)

        self._apiurl = self._bs.apiurl

        self._bdir = os.path.abspath(os.path.expanduser(basedir))
        self._prj = prj
        self._pkg = pkg
        self._pkgpath = os.path.join(self._bdir, prj, pkg)

        if not os.path.exists(self._bdir):
            os.makedirs(self._bdir)

        with Workdir(self._bdir):
            shutil.rmtree(prj, ignore_errors = True)

        realprj = self._bs.get_package_real_project_name(self._prj, self._pkg)
        print 'realprj', realprj
        if realprj:
            if realprj == self._prj:
                # to checkout server stuff
                self._checkout_latest()
            else:
                # branch from target project
                print "branch package %s from %s" % (self._pkg, realprj)
                self._bs.branch_pkg(realprj, self._pkg, \
                        target_project=self._prj)
                self._checkout_latest()
        else:
            # to init new package in local dir
            self._mkpac()

    def _mkpac(self):
        """Make a package in OBS"""
        print "mkpac %s %s" % (self._prj, self._pkg)
        with Workdir(self._bdir):
            self._bs.mk_pac(self._prj, self._pkg)

    def _checkout_latest(self):
        """ checkout the 'latest' revision of package with link expanded
        """
        print "checkout latest %s %s" % (self._prj, self._pkg)
        with Workdir(self._bdir):
            try:
                self._bs.checkout(self._prj, self._pkg)
            except buildservice.ObsError, err:
                raise ObsError(str(err))

    def status(self, filename):
        """Get the status of one single file
           The status could be ' ', 'A', 'C', 'D', 'M', '?', '!'
        """
        with Workdir(self._pkgpath):
            try:
                pac = core.findpacs([filename])[0]
                status = sorted(pac.get_status(), key=lambda x: x[1])[0][0]
            except oscerr.OscIOError:
                return '?'
            return status

    def is_new_pkg(self):
        """Check whether this is a new package in obs
        """
        packages = self._bs.get_package_list(self._prj)
        print "%s package list:" % self._prj, packages
        if self._pkg in packages:
            print "%s is NOT new package in %s" % (self._pkg, self._prj)
            return False
        else:
            print "%s is new package in %s" % (self._pkg, self._prj)
            return True 

    def get_workdir(self):
        """Get package path"""
        return self._pkgpath

    def remove_all(self):
        """Remove all files under pkg dir
        """

        with Workdir(self._pkgpath):
            runner.quiet('/bin/rm -f *')

    def commit(self, msg):
        """Submit a package change to OBS with msg"""
        with Workdir(self._pkgpath):
            self._bs.submit(msg)

    def submit_req(self, dst_prj, dst_pkg=None, msg='', supersede=True):
        """Submit request to obs dest project
        """
        if not dst_pkg:
            dst_pkg = self._pkg
        with Workdir(self._pkgpath):
            reqs = self._bs.get_request_list(dst_prj, dst_pkg)
            newreq = self._bs.submit_req(self._prj, self._pkg, dst_prj, \
                    dst_pkg, msg, src_update='cleanup')
            if supersede:
                for req in reqs:
                    self._bs.req_supersede(req.reqid, 'superseded by %s' % \
                            newreq, newreq)
        return newreq

