#!/usr/bin/ruby

# xpkg: Package build system for X/Qt project
#
# Copyright (C) 2003-2005 Takuya Murakami
#
# 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

$debug = false

$LOAD_PATH.push(File.expand_path(File.dirname($0)))
require "xpkg-common"

# load libraries
require "pkg"
require "install"
require "pkgbuild"
require "ipkg"
require "misc"
require "workstate"


class Xpkg
    include Misc

    # main
    def main
	# parse arguments
	target, command, deffiles = parse_opt()

	# setup directory parameters
	setupdirs(target)
	
	# load deffile
        pkgs = Array.new
        deffiles.each do |deffile|
            pkg = Pkg.new
            pkg.loaddef(deffile, target, @destdir, $sysconfdir)
            pkgs.push(pkg)
        end

	# handles World/DevelWorld arg
	cmds = nil
	if (command == "World")
	    cmds = ["source", "build", "install", "pkg"]
	elsif (command == "DevelWorld")
	    cmds = ["source", "build", "install", "pkg", "install-develpkg"]
	else
	    cmds = [command]
	end

	workstate = WorkState.new

	# build main loop
	st = Time.now
	cmds.each do |command|
            pkgs.each do |pkg|
                execBuildCommand(pkg, command, workstate)
            end
	end

	# show status
	tm = (Time.now - st).to_i

	sku = ENV["SKU"]
	if (sku != nil)
	    sk = sprintf(", %f SKU", (tm / sku.to_f * 1000).to_i / 1000.0)
	else
	    sk = ""
	end
	puts "----- Compile time: #{tm} sec (#{tm / 60}:#{tm % 60}#{sk})."
	puts "done."
	exit 0
    end

    # build one module
    def execBuildCommand(pkg, command, workstate)
	return if (command != "clear" && workstate.done?(command))

        puts "----- Execute #{command} with #{pkg.deffile}"
        begin
            # switch command
            case command
            when "source"
                pkg.getSource(@distfiledir)
                pkg.execSectionScript("prep")
                pkg.execSectionScript("patch") # backword compatilibity

            when "download"
                pkg.getSource(@distfiledir, true)

            when "pkg", "ipkg"
                getPkgBuild(pkg).Build
                
            when "install-pkg", "install-ipkg"
                getPkgBuild(pkg).InstallLocal()

            when "install-develpkg"
                getPkgBuild(pkg).InstallDevelPackage()

            when "cleanup"
                pkg.cleanup()

            when "clear"
                # do nothing, clear state only

            else
                pkg.execSectionScript(command)
            end
            
        rescue
            STDERR.puts $!
            if (command != "ipkg")
                STDERR.puts "Abort."
                exit 1
            end
        end

	if (command == "cleanup" || command == "clear")
	    workstate.clear
	else
	    workstate.setdone(command)
	end
	workstate.save
    end

    # create PkgBuild instance
    def getPkgBuild(pkg)
        case pkg.df.getDefine("pkgtype")
        when "ipkg"
            pkgbuild = IpkgBuild.new
            pkgbuild.SetIpkgParam("#{$pkglibdir}/ipkg-build")
        else
            pkgbuild = GenPkgBuild.new
        end
        pkgbuild.SetParam(pkg.df, @destdir, @pkgdir, @develpkgdir, ".")
        return pkgbuild
    end

    # Parse command line option
    def parse_opt
	# build target
	target = ENV["TARGET"]
	if (target == nil || target == "")
	    target = $default_target  # default value
	end

	# setup option parser
	opt = OptionParser.new
        opt.banner = "xpkg version #{$version}\n" + $copyright + 
                 "Usage: xpkg [option...] [command] [deffile...]"
	opt.on_head(" command: source|build|clean|cleanup|pkg|install-develpkg|install-pkg\n option:")

	opt.on("-h", "--help", "Show this message") { puts opt; exit 1; }
	opt.on("-t", "--target=TARGET", String, "Specify target") {|v| target = v }
	opt.on("-v", "--verbose", "Verbose") {$verbose = true}

	opt.parse!(ARGV)
	
	if (ARGV.size < 1)
	    puts opt
	    exit 1
	end

	command = ARGV.shift
	deffiles = ARGV
	
        # handle pkgdef.list
        if (deffiles.size == 0)
            if (FileTest.exist?("pkgdef.list"))
                IO.readlines("pkgdef.list").each do |file|
                    file.chop!
                    file.strip!
                    next if (file == "" || file =~ /^#/)

		    if (!File.exist?(file))
			STDERR.puts "#{file} does not exist."
			exit 1
		    end
                    deffiles.push(file)
                end
            else
                if (!File.exist?("pkgdef"))
                    STDERR.puts "pkgdef does not exist."
                    exit 1
                end
                deffiles = ["pkgdef"]
            end
        end

	return target, command, deffiles
    end
end

xpkg = Xpkg.new
xpkg.main
