#!/usr/bin/python
#
# Copyright (c) SAS Institute Inc.
#
# Licensed 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.
#



import os

from rbuild_test import rbuildhelp
from testutils import mock

from conary.lib import util
from conary import state

from rbuild import errors

from rpath_proddef import api1 as proddef
from rbuild.productstore import dirstore

from rbuild.facade import conaryfacade
from rbuild_test.unit_test.facadetest import conaryfacadetest

class DirStoreTest(rbuildhelp.RbuildHelper):
    def _prepProductStore(self):
        os.chdir(self.workDir)
        util.mkdirChain('foo/.rbuild/product-definition')
        self.writeFile(
                    'foo/.rbuild/product-definition/product-definition.xml', '')
        util.mkdirChain('foo/stable')
        self.writeFile('foo/stable/.stage', 'stable\n')
        from rbuild.productstore import abstract
        mock.mock(abstract.ProductStore, 'checkStageIsValid')

    def testCheckoutProductStore(self):
        self._prepProductStore()
        util.mkdirChain('foo/stable/package')
        os.chdir('foo/stable/package')
        handle = self.getRbuildHandle(productStore=mock.MockObject())
        productStore = dirstore.CheckoutProductStore(handle)
        self.assertEquals(productStore.getBaseDirectory(),
            self.workDir + '/foo')
        self.assertEquals(productStore.getActiveStageName(), 'stable')
        productStore = dirstore.CheckoutProductStore(handle,
            baseDirectory=self.workDir + '/foo')
        self.assertEquals(productStore.getBaseDirectory(),
            self.workDir + '/foo')

    def testGetDefaultProductDirectory(self):
        self._prepProductStore()
        productDirectory = dirstore.getDefaultProductDirectory('foo/stable')
        # relative path
        self.assertEquals(productDirectory, 'foo')

        os.chdir('foo/stable')
        # starts with os.getcwd() so will be absolute path
        productDirectory = dirstore.getDefaultProductDirectory()
        self.assertEquals(productDirectory, self.workDir + '/foo')

        self.assertRaises(errors.MissingProductStoreError,
            dirstore.getDefaultProductDirectory, 'directoryDoesNotExist')

        os.chdir('/')
        self.assertRaises(errors.MissingProductStoreError,
            dirstore.getDefaultProductDirectory, error=True)

    def testGetStageNameFromDirectory(self):
        self._prepProductStore()
        stageName = dirstore.getStageNameFromDirectory('foo/stable')
        assert stageName == 'stable'
        os.chdir('foo/stable')
        stageName = dirstore.getStageNameFromDirectory('.')
        assert stageName == 'stable'
        stageName = dirstore.getStageNameFromDirectory()
        assert stageName == 'stable'

    def testProductStoreError(self):
        handle = self.getRbuildHandle()
        err = self.assertRaises(errors.RbuildError, 
                    dirstore.CheckoutProductStore, handle, self.workDir)
        assert(str(err) == "No product directory at '%s'" % self.workDir)
        err = self.assertRaises(errors.RbuildError, 
                    dirstore.CheckoutProductStore, handle)
        assert(str(err) == "Could not find product directory")

    def testCore(self):
        handle = self.getRbuildHandle()
        productClass = mock.MockObject(stableReturnValues=True)
        stage = mock.MockObject(label='localhost@rpl:1')
        productClass().getStage._mock.setReturn(stage, 'foo')
        productClass._mock.popCall()
        self.mock(proddef, 'ProductDefinition', productClass)
        os.chdir(self.workDir)
        util.mkdirChain('foo/.rbuild/product-definition')
        self.writeFile('foo/.rbuild/product-definition/product-definition.xml',
                       '')

        p = dirstore.CheckoutProductStore(handle, 'foo')
        err = self.assertRaises(errors.RbuildError, p.getActiveStageName)
        self.assertEquals(str(err), 'No current stage (setActiveStageName)')
        mock.mock(dirstore.CheckoutProductStore, 'checkStageIsValid')
        p.setActiveStageName('foo')
        assert(p.getActiveStageName() == 'foo')

        proddefObj = p.getProduct()
        _, kw = productClass._mock.popCall()
        kw = dict(kw)
        kw.pop('fromStream')

        configPath = self.workDir + '/foo/.rbuild/product-definition/rmakerc'
        self.assertEquals(p.getRmakeConfigPath(), configPath)