# GLINT graphical package management
# Copyright (C) 1995 Red Hat, 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; either version 2 of the License, or
# (at your option) any later version.
#
# 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., 675 Mass Ave, Cambridge, MA 02139, USA.

import string
import regex
import regsub

class File:
    def setState(self, state):
	self.state = state;

    def getState(self): return self.state
    def getName(self): return self.name
    def getSize(self): return self.size
    def getMtime(self): return self.mtime
    def getMd5(self): return self.md5
    def getMode(self): return self.mode
    def getUid(self): return self.uid
    def getGid(self): return self.gid
    def isConfig(self): return self.isconf == "1"
    def isDoc(self): return self.isdoc == "1"
    def getRdev(self): return self.rdev
    def getLink(self): return self.link

    def __init__(self, seq):
	(self.name, self.size, self.mtime, self.md5,
	 self.mode, self.uid, self.gid, self.isconf,
	 self.isdoc, self.rdev, self.link) = seq;

class FileEntry(File):
    def __init__(self, s):
	self.infoline = s
	[self.name, self.size, self.mtime, self.md5,
	 self.mode, self.uid, self.gid, self.isconf,
	 self.isdoc, self.rdev, self.link] = string.split(s)
	self.state = "Unknown"

class Speci:
    packageR = regex.compile("^%package", regex.casefold);
    speciR = regex.compile("^%speci", regex.casefold);
    preR = regex.compile("^%pre", regex.casefold);
    postR = regex.compile("^%post", regex.casefold);
    sizeR = regex.compile("^size:", regex.casefold);
    nameR = regex.compile("^name:", regex.casefold);
    versionR = regex.compile("^version:", regex.casefold);
    releaseR = regex.compile("^release:", regex.casefold);
    buildhostR = regex.compile("^buildhost:", regex.casefold);
    builddateR = regex.compile("^builddate:", regex.casefold);
    distributionR = regex.compile("^distribution:", regex.casefold);
    vendorR = regex.compile("^vendor:", regex.casefold);
    descriptionR = regex.compile("^description:", regex.casefold);
    stripFirstTokenR = regex.compile("^[^ \t]*[ \t]*");

    def __init__(self):
	self.name = ""
	self.subname = ""
	self.version = ""
	self.release = ""
	self.size = 0
	self.buildhost = ""
	self.builddate = 0
	self.distribution = ""
	self.vendor = ""
	self.description = ""
	self.preamble = ""
	self.pre = ""
	self.post = ""

    def getName(self): return self.name
    def getVersion(self): return self.version
    def getRelease(self): return self.release
    def getSize(self): return self.size
    def getBuildhost(self): return self.buildhost
    def getBuilddate(self): return self.builddate
    def getDistribution(self): return self.distribution
    def getVendor(self): return self.vendor
    def getDescription(self): return self.description
    def getFileEntries(self): return self.fileEntry

class SpeciFromFile(Speci):
    def __init__(self, speci):
	Speci.__init__(self)
	self.speci = speci
	self.fileEntry = {}

    def parse(self):
	stage = "package"
	indesc = 0
	for line in string.splitfields(self.speci, '\n'):
	    l = string.split(line)
	    arg = ""
	    if (len(l) == 0): continue
	    if (len(l) > 1): arg = l[1]
	    args = line
	    args = regsub.sub(self.stripFirstTokenR, "", args)

	    if (self.packageR.match(line) > -1): stage = "package"
	    if (self.speciR.match(line) > -1):
		stage = "speci"
		continue
	    if (self.preR.match(line) > -1):
		stage = "pre"
		continue
	    if (self.postR.match(line) > -1):
		stage = "post"
		continue

	    if (stage == "package"):
		if (self.packageR.match(line) > -1):
		    self.subname = arg
		    continue
		elif (self.nameR.match(line) > -1):
		    self.name = arg
		    continue
		elif (self.versionR.match(line) > -1):
		    self.version = arg
		    continue
		elif (self.releaseR.match(line) > -1):
		    self.release = arg
		    continue
		elif (self.sizeR.match(line) > -1):
		    self.size = string.atoi(arg)
		    continue
		elif (self.buildhostR.match(line) > -1):
		    self.buildhost = arg
		    continue
		elif (self.builddateR.match(line) > -1):
		    self.builddate = string.atoi(arg)
		    continue
		elif (self.distributionR.match(line) > -1):
		    # This can be multiple tokens
		    self.distribution = args
		    continue
		elif (self.vendorR.match(line) > -1):
		    # This can be multiple tokens
		    self.vendor = args
		    continue
		elif (self.descriptionR.match(line) > -1):
		    self.description = line
		    self.description = regsub.sub(self.stripFirstTokenR, "", self.description)
		    string.strip(self.description)
		    x = len(self.description) - 1
		    if (self.description[x] == "\\"):
			self.description = self.description[:(x-1)]
			indesc = 1
		    continue

		# Chomp any remaining description lines
		if (indesc == 1):
		    self.description = "%s\n%s" % (self.description, line)
		    x = len(self.description) - 1
		    if (self.description[x] == "\\"):
			self.description = self.description[:(x-1)]
			indesc = 1
		    else:
			indesc = 0
		    continue
		    
		# Anything else is "preamble"
		self.preamble = "%s\n%s" % (self.preamble, line)
		continue

	    elif (stage == "pre"):
		self.pre = "%s\n%s" % (self.pre, line)
		continue
	    elif (stage == "post"):
		self.post = "%s\n%s" % (self.post, line)
		continue
	    elif (stage == "speci"):
		f = string.split(line)[0]
		self.fileEntry[f] = FileEntry(line)

class SpeciFromStr(Speci):

    # these need to match the corresponding lines in rpm's dbrecord.pl
    # or things will break *badly*

    subpackage = "subpackage"
    recfields = ("name", "version", "release", subpackage + "C")
    files = "file"
    subpackagefields = ("name", "preamble", "insttime", files + "C")
    filefields = ("path", "state", "info")

    def __init__(self, str):
	Speci.__init__(self)
	self.str = str
	self.fileEntry = {}
	self.parse()

    def parse(self):
	a = string.splitfields(self.str, "\1")

	count = 0;
	for field in self.recfields:
	    if (field == "name"):
		self.name = a[count]
	    elif (field == "version"):
		self.version = a[count]
	    elif (field == "release"):
		self.release = a[count]
	    elif (field == self.subpackage + "C"):
		pass

	    count = count + 1

	for field in self.subpackagefields:
	    if (field == "name"):
		self.name = self.name + "-" + a[count]
	    elif (field == "preamble"):
		self.preamble = a[count]
		for line in string.splitfields(self.preamble, "\n"):
		    l = string.split(line)
		    arg = ""
		    if (len(l) == 0): continue
		    if (len(l) > 1): arg = l[1]
		    args = line
		    args = regsub.sub(self.stripFirstTokenR, "", args)

		    if (self.buildhostR.match(line) > 1):
			self.buildhost = args
		    elif (self.builddateR.match(line) > 1):
			self.builddate = string.atoi(arg)
		    elif (self.distributionR.match(line) > 1):
			self.distribution = args
		    elif (self.vendorR.match(line) > 1):
			self.vendor = args
		    elif (self.descriptionR.match(line) > 1):
			self.description = args
	    elif (field == "insttime"):
		self.insttime = a[count]
	    elif (field == self.files + "C"):
		numfiles = string.atoi(a[count])
	    count = count + 1
	
	for j in range(numfiles):
	    state = "Unknown"
	    for field in self.filefields:
		if (field == "path"):
		    path = a[count]
		elif (field == "state"):
		    state = a[count]
		elif (field == "info"):
		    info = a[count]
		count = count + 1
	    self.fileEntry[path] = FileEntry(path + " " + info)
	    self.fileEntry[path].setState(state)

