#!/usr/bin/env python

import os, random, sys, time, urllib

#
# Options
#

dry_run = len(sys.argv) > 1 and "--dry-run" in set(sys.argv[1:])
quiet = len(sys.argv) > 1 and "--quiet" in set(sys.argv[1:])

#
# Functions and constants
#

def download_progress_hook(block_count, block_size, total_blocks):
        if quiet or random.random() > 0.5:
                return
        sys.stdout.write(".")
        sys.stdout.flush()

def download_url_to_file(url, file, message):
        if not quiet:
                print message + " ",
        if not dry_run:
                dir = os.path.dirname(file)
                if len(dir) and not os.path.exists(dir):
                    os.makedirs(dir)
                urllib.urlretrieve(url, file, download_progress_hook)
        if not quiet:
                print
 
# This is mostly just the list of North America http mirrors from http://cygwin.com/mirrors.html,
# but a few have been removed that seemed unresponsive from Cupertino.
mirror_servers = ["http://cygwin.elite-systems.org/",
                  "http://mirror.mcs.anl.gov/cygwin/",
                  "http://cygwin.osuosl.org/",
                  "http://mirrors.kernel.org/sourceware/cygwin/",
                  "http://mirrors.xmission.com/cygwin/",
                  "http://sourceware.mirrors.tds.net/pub/sourceware.org/cygwin/"]

package_mirror_url = mirror_servers[random.choice(range(len(mirror_servers)))]

def download_package(package, message):
        download_url_to_file(package_mirror_url + package["path"], package["path"], message)

required_packages = frozenset(["bc",
                               "bison",
                               "curl",
                               "diffutils",
                               "e2fsprogs",
                               "emacs",
                               "flex",
                               "gcc-g++",
                               "gperf",
                               "keychain",
                               "lighttpd",
                               "make",
                               "nano",
                               "openssh",
                               "patch",
                               "perl",
                               "perl-libwin32",
                               "python",
                               "rebase",
                               "rsync",
                               "ruby",
                               "subversion",
                               "unzip",
                               "vim",
                               "zip"])

required_packages_versions = {"curl": "7.33.0-1",
                              "libcurl4": "7.33.0-1",
                              "python": "2.6.8-2",
                              "subversion": "1.7.14-1"}

#
# Main
#

print "Using Cygwin mirror server " + package_mirror_url + " to download setup.ini..."

urllib.urlretrieve(package_mirror_url + "x86/setup.ini", "setup.ini.orig")

downloaded_packages_file_path = "setup.ini.orig"
downloaded_packages_file = file(downloaded_packages_file_path, "r")
if not dry_run:
    modified_packages_file = file("setup.ini", "w")

packages = {}
current_package = ''
for line in downloaded_packages_file.readlines():
        if line[0] == "@":
                current_package = line[2:-1]
                packages[current_package] = {"name": current_package, "needs_download": False, "requires": [], "path": "", "version": "", "found_version": False}
                if current_package in required_packages_versions:
                        packages[current_package]["version"] = required_packages_versions[current_package]
        elif line[:10] == "category: ":
                if current_package in required_packages:
                        line = "category: Base\n"
                if "Base" in set(line[10:-1].split()):
                        packages[current_package]["needs_download"] = True
        elif line[:10] == "requires: ":
                packages[current_package]["requires"] = line[10:].split()
                packages[current_package]["requires"].sort()
        elif line[:9] == "version: " and not packages[current_package]["found_version"]:
                if not len(packages[current_package]["version"]):
                        packages[current_package]["version"] = line[9:-1]
                        packages[current_package]["found_version"] = True
                else:
                        packages[current_package]["found_version"] = (packages[current_package]["version"] == line[9:-1])
        elif line[:9] == "install: " and packages[current_package]["found_version"] and not len(packages[current_package]["path"]):
                end_of_path = line.find(" ", 9)
                if end_of_path != -1:
                        packages[current_package]["path"] = line[9:end_of_path]
        if not dry_run:
            modified_packages_file.write(line)

downloaded_packages_file.close()
os.remove(downloaded_packages_file_path)
if not dry_run:
    modified_packages_file.close()

names_to_download = set()
package_names = packages.keys()
package_names.sort()

def add_package_and_dependencies(name):
        if name in names_to_download:
                return
        if not name in packages:
                return
        packages[name]["needs_download"] = True
        names_to_download.add(name)
        for dep in packages[name]["requires"]:
                add_package_and_dependencies(dep)

for name in package_names:
        if packages[name]["needs_download"]:
                add_package_and_dependencies(name)

downloaded_so_far = 0
for name in package_names:
        if packages[name]["needs_download"]:
                downloaded_so_far += 1
                download_package(packages[name], "Downloading package %3d of %3d (%s)" % (downloaded_so_far, len(names_to_download), name))

download_url_to_file("http://cygwin.com/setup-x86.exe", "setup.exe", "Downloading setup.exe")

seconds_to_sleep = 10

print """
Finished downloading Cygwin. In %d seconds,
I will run setup.exe. All the suitable options have
been already selected for you.
""" % (seconds_to_sleep)


while seconds_to_sleep > 0:
        print "%d..." % seconds_to_sleep,
        sys.stdout.flush()
        time.sleep(1)
        seconds_to_sleep -= 1
print

if not dry_run:
        os.execv("setup.exe", list(("-L", "-l", os.getcwd(), "-P", ",".join(required_packages))))
