from Server.Server.SCore import test_helper
from Ft.Lib.Uri import OsPathToUri
from Ft.Server.Common.Install import InstallUtil
import tempfile, os, time, sha

import Server
BASE_DIR = os.path.join(os.path.dirname(Server.__file__), 'Common', 'Install')

def init(tester):

    tester.startTest("Init")
    repo = test_helper.GetRepo(tester)

    if repo.hasResource('/test'):
        repo.deleteResource('/test')

    repo.createContainer('/test')
    repo.txCommit()
    tester.testDone()

def test_container(tester):

    tester.startTest("Container Up-to-Date")
    repo = test_helper.GetRepo(tester)
    c = InstallUtil.Container('/test/cont1', [], None, None, None)
    tester.compare(InstallUtil.StatusFlags.ACTION_REQUIRED, c.checkStatus(repo))
    tester.compare(InstallUtil.StatusFlags.ACTION_REQUIRED, c.checkStatus(repo))
    repo.createContainer('/test/cont1')
    clearCache()
    tester.compare(InstallUtil.StatusFlags.NO_CHANGE, c.checkStatus(repo, force=1))
    repo.txCommit()
    tester.testDone()

    tester.startTest("Owner Changes")
    repo = test_helper.GetRepo(tester)
    tester.compare(InstallUtil.StatusFlags.NO_CHANGE, c.checkStatus(repo))
    repo.fetchResource('/test/cont1').setOwner(repo.fetchUserOrGroupByName('super-users'))
    clearCache()
    c.owner = tester.test_data['userName']
    tester.compare(InstallUtil.StatusFlags.OWNER_CHANGE, c.checkStatus(repo, force=1))

    repo.txCommit()
    tester.testDone()

    tester.startTest("ACL Adds")
    repo = test_helper.GetRepo(tester)
    clearCache()
    c._setAcl([('read', 'super-users', 1)])
    c.owner = None
    tester.compare(InstallUtil.StatusFlags.ACL_CHANGE, c.checkStatus(repo, force=1))
    repo.fetchResource('/test/cont1').setAcl('read', 'super-users', 1)
    repo.txCommit()
    tester.testDone()

    tester.startTest("ACL Modify")
    repo = test_helper.GetRepo(tester)
    clearCache()
    c.acl = [('read', 'owner', 1)]
    tester.compare(InstallUtil.StatusFlags.ACL_CHANGE, c.checkStatus(repo, force=1))

    clearCache()
    c._setAcl([('read', 'super-users', 0)])
    tester.compare(InstallUtil.StatusFlags.ACL_CHANGE, c.checkStatus(repo, force=1))

    clearCache()
    c._setAcl([('read', 'super-users', 1), ('write', 'owner', 1)])
    tester.compare(InstallUtil.StatusFlags.ACL_CHANGE, c.checkStatus(repo, force=1))

    repo.txRollback()
    tester.testDone()

    tester.startTest("ACL Remove")
    repo = test_helper.GetRepo(tester)
    clearCache()
    c._setAcl([])
    tester.compare(InstallUtil.StatusFlags.ACL_CHANGE, c.checkStatus(repo, force=1))
    repo.txRollback()
    tester.testDone()


def test_rawfile(tester):

    tester.startTest("Rawfile Up-to-Date")
    repo = test_helper.GetRepo(tester)
    r = InstallUtil.RawFile('/test/test1.html', [], None, None)
    r.setPath(OsPathToUri(os.path.join(BASE_DIR, 'test1.html')))
    tester.compare(InstallUtil.StatusFlags.ACTION_REQUIRED, r.checkStatus(repo))
    repo.txRollback()
    tester.testDone()

    tester.startTest("No Content Change")
    repo = test_helper.GetRepo(tester)
    repo.createRawFile('/test/test1.html', 'text/html', '<html>')
    #Created is newer then on disk
    r = InstallUtil.RawFile('/test/test1.html', [], None, 'text/html')
    r.setPath(OsPathToUri(os.path.join(BASE_DIR, 'test1.html')))
    clearCache()
    tester.compare(InstallUtil.StatusFlags.NO_CHANGE, r.checkStatus(repo))
    repo.txCommit()
    tester.testDone()

    time.sleep(1)  #Just to make sure they are different
    tf = tempfile.mktemp()
    tester.startTest("Content Change")
    repo = test_helper.GetRepo(tester)
    r = InstallUtil.RawFile('/test/test1.html', [], None, 'text/html')
    InstallUtil.RawFile.lmds = None   #Reset the cache
    InstallUtil.RawFile.imts = {}   #Reset the cache
    InstallUtil.RawFile.owners = {}   #Reset the cache
    open(tf, 'w').write('<html>')
    r.setPath(OsPathToUri(tf))
    clearCache()
    tester.compare(InstallUtil.StatusFlags.CONTENT_CHANGE, r.checkStatus(repo, force=1))
    repo.txCommit()
    os.unlink(tf)
    tester.testDone()

    tester.startTest("IMT Changes")
    repo = test_helper.GetRepo(tester)
    r = InstallUtil.RawFile('/test/test1.html', [], None, 'text/plain')
    clearCache()
    tester.compare(InstallUtil.StatusFlags.IMT_CHANGE, r.checkStatus(repo, force=1))
    repo.txCommit()
    tester.testDone()


def test_xmldocument(tester):
    tester.startTest("Xmldocument Up-to-Date")
    repo = test_helper.GetRepo(tester)
    r = InstallUtil.XmlDocument('/test/test1.xml', [], None, None, None)
    r.setPath(OsPathToUri(os.path.join(BASE_DIR, 'test1.xml')))
    tester.compare(InstallUtil.StatusFlags.ACTION_REQUIRED, r.checkStatus(repo))
    repo.txRollback()
    tester.testDone()

    tester.startTest("Doc Def Change")
    repo = test_helper.GetRepo(tester)
    repo.createDocument('/test/test1.xml', '<foo/>')
    r = InstallUtil.XmlDocument('/test/test1.xml', [], None, None, 'foo.dd')
    r.setPath(OsPathToUri(os.path.join(BASE_DIR, 'test1.html')))
    clearCache()
    tester.compare(InstallUtil.StatusFlags.OTHER_CHANGE, r.checkStatus(repo))
    repo.txCommit()
    tester.testDone()


def test_user(tester):

    tester.startTest("User Up-to-Date")
    repo = test_helper.GetRepo(tester)
    r = InstallUtil.User('test-user', [], None, None, None, '/test', 'test')
    tester.compare(InstallUtil.StatusFlags.ACTION_REQUIRED, r.checkStatus(repo))
    repo.fetchResource('/test').createUser('test-user', sha.new('test2').hexdigest())
    repo.txCommit()
    tester.testDone()


    tester.startTest("Password Change")
    repo = test_helper.GetRepo(tester)
    r = InstallUtil.User('test-user', [], None, None, None, '/test', 'test')
    clearCache()
    tester.compare(InstallUtil.StatusFlags.OTHER_CHANGE | InstallUtil.StatusFlags.ACL_CHANGE, r.checkStatus(repo))
    repo.txRollback()
    tester.testDone()

def test_group(tester):

    tester.startTest("Group Up-to-Date")
    repo = test_helper.GetRepo(tester)
    r = InstallUtil.Group('test-group', [], None, None, None, '/test', ['test-user'])
    tester.compare(InstallUtil.StatusFlags.ACTION_REQUIRED, r.checkStatus(repo))
    g = repo.fetchResource('/test').createGroup('test-group')
    repo.txCommit()
    tester.testDone()

    tester.startTest("Member Change")
    repo = test_helper.GetRepo(tester)
    r = InstallUtil.Group('test-group', [], None, None, None, '/test', ['test-user'])
    clearCache()
    tester.compare(InstallUtil.StatusFlags.OTHER_CHANGE | InstallUtil.StatusFlags.ACL_CHANGE, r.checkStatus(repo))
    repo.txRollback()
    tester.testDone()

def test_alias(tester):

    tester.startTest("Alias Up-to-Date")
    repo = test_helper.GetRepo(tester)
    r = InstallUtil.Alias('/test/test1.alias', [], None, None, None, '/test/test1.xml')
    tester.compare(InstallUtil.StatusFlags.ACTION_REQUIRED, r.checkStatus(repo))
    a = repo.fetchResource('/test/test1.html').addAlias('test1.alias')
    repo.txCommit()
    tester.testDone()

    tester.startTest("Reference Change")
    repo = test_helper.GetRepo(tester)
    r = InstallUtil.Alias('/test/test1.alias', [], None, None, None, '/test/test1.xml')
    clearCache()
    tester.compare(InstallUtil.StatusFlags.OTHER_CHANGE, r.checkStatus(repo))
    repo.txCommit()
    tester.testDone()

def test_urireference(tester):

    tester.startTest("Uri Reference Up-to-Date")
    repo = test_helper.GetRepo(tester)
    r = InstallUtil.UriReferenceFile('/test/test1.uri', [], None, None, '/test/test1.html')
    tester.compare(InstallUtil.StatusFlags.ACTION_REQUIRED, r.checkStatus(repo))
    a = repo.fetchResource('/test').createUriReferenceFile('test1.uri', 'text/plain', OsPathToUri(os.path.join(BASE_DIR, 'test_uptodate.py')))
    repo.txCommit()
    tester.testDone()

    tester.startTest("Uri Reference Change of Reference")
    repo = test_helper.GetRepo(tester)
    r = InstallUtil.UriReferenceFile('/test/test1.uri', [], None, None, '/test/test1.html')
    clearCache()
    tester.compare(InstallUtil.StatusFlags.OTHER_CHANGE, r.checkStatus(repo))
    repo.txCommit()
    tester.testDone()



def clearCache():
    InstallUtil.RawFile.lmds = None   #Reset the cache
    InstallUtil.RawFile.imts = {}   #Reset the cache
    InstallUtil.RawFile.owners = {}   #Reset the cache
    InstallUtil.XmlDocument._dds = None   #Reset the cache
    InstallUtil.Alias._refs = None   #Reset the cache
    InstallUtil.UriReferenceFile._refs = None   #Reset the cache


def Test(tester):

    init(tester)
    test_container(tester)
    test_rawfile(tester)
    test_xmldocument(tester)
    test_user(tester)
    test_group(tester)
    test_alias(tester)
    test_urireference(tester)
