// Copyright 2017 - 2021 the Open GEE Contributors
//
// 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.
//
//
// This file is 'earth_enterprise/rpms/build.gradle'
//
// Command-line parameters:
//
//     ./gradlew -PbuildOpenGee:
// Compile and install Open GEE in a temporary directory before packaging.
// If you don't specify `-PbuildOpenGee` on the Gradle command line, no
// compilation, or installation are run.  In that case, you must ensure the
// main scons "stage_install" target has been called before building packages.
// This Scons target copies build artifacts, binaries and documents into the
// /tmp/fusion_os_install path.
//
//     ./gradlew -Pdebug
// Build the RPMs using the files in 'NATIVE-DBG-x86_64'
//
//     ./gradlew -Poptimize
// Build the RPMs using the files in 'NATIVE-OPT-x86_64'
//
//
// See documentation on the osPackage plugin here:
//
// https://github.com/nebula-plugins/gradle-ospackage-plugin


buildscript {
    repositories {
        jcenter()
    }

    dependencies {
        classpath 'com.netflix.nebula:gradle-ospackage-plugin:8.2.0'
    }
}

apply plugin: "nebula.ospackage"

import org.opengee.shell.GeeCommandLine
import org.opengee.io.CopySpecTemplates

def stagedInstall_path =
    project.hasProperty('stageInstallPath') ? project.stageInstallPath : '/tmp/fusion_os_install'

if (new File('build.properties').exists()) {
    def props = new Properties()
    new File('build.properties').withInputStream {
        props.load(it)
    }
    if (props["staged"]) {
        stagedInstall_path = props["staged"]
    }
}

// Look for command line parameters that specify how the packages are
// to be built.  This can be either 'optimize' or 'debug'.
// Option 'release' is the default.
def scons_option = "release=1"

if ( project.hasProperty( 'optimize' ) ) {
    scons_option = "optimize=1"
}  // end check for option 'optimze'
else if ( project.hasProperty( 'debug' ) || project.hasProperty( 'internal' ) ) {
    scons_option = "internal=1"
}

def rpmPlatformString = org.opengee.os.Platform.rpmPlatformString

// Get the version of OpenGEE we're building:
def gee_long_version_txt = "${stagedInstall_path}/gee_long_version.txt"
def openGeeVersionFile = new File( gee_long_version_txt )

ext.getOsPackageVersionFromOpenGeeVersion = { value -> 
    return value.split('-')[0]
}

ext.getOsPackageBuildFromOpenGeeVersion = { value ->
    return value.split('-')[1]
}

def getOsPackageVersionOrBuildFromOpenGeeVersionFile(file, getString) {
    return getString(
        file.readLines().
        collect {
            // Strip comments:
            def commentIndex = it.indexOf('#')

            commentIndex < 0 ? it : it.substring(0, commentIndex)
        }.
        collect { it.trim() }. // Trim whitespace.
        findAll { !it.isEmpty() }. // Skip empty lines.
        findResult {
            it // The first string that remains is the version string.
        }
    )
}

def getOsPackageVersionFromOpenGeeVersionFile(file) {
    return getOsPackageVersionOrBuildFromOpenGeeVersionFile(
        file,
        getOsPackageVersionFromOpenGeeVersion
    )
}

def getOsPackageBuildFromOpenGeeVersionFile(file) {
    return getOsPackageVersionOrBuildFromOpenGeeVersionFile(
        file,
        getOsPackageBuildFromOpenGeeVersion
    )
}



def stagedInstallDir = new File(stagedInstall_path)
def stagedInstallDir_common_opt = new File(stagedInstallDir, 'common/opt')
def stagedInstallDir_common_user_magic =
    new File(stagedInstallDir, 'common/user_magic')
def stagedInstallDir_manual = new File(stagedInstallDir, 'manual')
def stagedInstallDir_server_opt = new File(stagedInstallDir, 'server/opt')
def stagedInstallDir_server_etc = new File(stagedInstallDir, 'server/etc')
def stagedInstallDir_server_searchexample =
    new File(stagedInstallDir, 'searchexample/opt/google/share/searchexample')
def stagedInstallDir_server_geplaces =
    new File(stagedInstallDir, 'geplaces/opt/google/share/geplaces')
def stagedInstallDir_server_user_magic =
    new File(stagedInstallDir, 'server/user_magic')
def stagedInstallDir_fusion = new File(stagedInstallDir, 'fusion')
def stagedInstallDir_tutorial = new File(stagedInstallDir, 'tutorial')
def packageInstallRootDir = new File('/')
def packageInstallLibDir = new File(packageInstallRootDir, 'opt/google/lib')

def stagedInstallDir_postgis_opt = new File(stagedInstallDir, 'postgis/opt')

// Commands used in install-utils.sh:
def packageSharedCommands = ['bash', 'flock', 'sed', 'xmllint']

// Since some libraries (i.e., MrSid)  cannot be redistributed without
// a license and are not packaged as an RPM, we need to filter these
// out from the automatic 'requires' dependency generation.
//     Since </bin> is symlinked to </usr/bin> on Cent OS 7, some
// build scripts misdetect the location of interpreters and utilities,
// such as `perl` and `sudo`.  The RPM packages for those utilities
// only provide RPM capabilities at the canonical paths
// (`/usr/bin/perl` and `/usr/bin/sudo`), so dependency resolution
// breaks, if non-canonical paths are used in `requires` headers.
//
// Capabilities mapped to `null` are removed from the dependency list.
// The ones mapped to strings are rewritten.
def rpmCapabilityMap = [
    'libltidsdk.so()(64bit)': null,
    '/bin/perl': '/usr/bin/perl',
    '/bin/python': '/usr/bin/python',
    '/bin/sudo': '/usr/bin/sudo'
]

// A lambda that can be set as an `autoFindRequiresFilter` in `GeeRpm` tasks.
//  It will use `rpmCapabilityMap` to rewrite RPM capabilities output by
// `find-requires`.
def rpmCapabilityFilter = {
    if (rpmCapabilityMap.containsKey(it.name)) {
        def newName = rpmCapabilityMap[it.name]

        return newName == null ?
            null :
            new org.opengee.os.package.Dependency(
                newName, it.version, it.flags)
    }

    return it
}

// A lambda that can be set as a `requiresCommandFilter` in `GeeRpm` tasks.
// It will use `rpmCapabilityMap` to rewrite command paths returned by `type`.
def rpmCommandFilter = {
    return rpmCapabilityMap.containsKey(it) ? rpmCapabilityMap[it] : it
}

// A lambda to figure out the best way to get the build number
def findBuildNumber = {
    return (!openGeeVersionFile.exists() || project.hasProperty('buildOpenGee')) ?
        getOsPackageBuildFromOpenGeeVersion(GeeCommandLine.expand(
                ["${projectDir}/../src/scons/getversion.py", "--long"],
                "Failed to get Open GEE build!"
            )) :
        getOsPackageBuildFromOpenGeeVersionFile(openGeeVersionFile)
}

// A lambda to figure out the best way to get the version number
def findVersionNumber = {
    return (!openGeeVersionFile.exists() || project.hasProperty('buildOpenGee')) ?
        getOsPackageVersionFromOpenGeeVersion(GeeCommandLine.expand(
                ["${projectDir}/../src/scons/getversion.py", "--long"],
                "Failed to get Open GEE version!"
            )) :
        getOsPackageVersionFromOpenGeeVersionFile(openGeeVersionFile)
}

ospackage {
    release = "${findBuildNumber()}.${rpmPlatformString}"
    distribution = rpmPlatformString
    packager = 'gee-oss@googlegroups.com'
    vendor = 'The OpenGEE Contributors'
    arch = X86_64
    os = LINUX
    version = "${findVersionNumber()}"
}

logger.quiet("Open GEE version: ${ospackage.version}")

// Build packages for the current platform by default:
defaultTasks 'osPackage'


task compileOpenGee(type: Exec) {
    workingDir = '..'
    commandLine('scons', '-j8', scons_option, 'build')
}

task stageOpenGeeInstall(type: Exec, dependsOn: 'compileOpenGee') {
    workingDir = '..'

    // The scons `stage_install` task doesn't work correctly with
    // "installdir=${build_install_dir.getAbsolutePath()}", so we
    // overwrite whatever is in the default stage install directory:
    commandLine(
        'scons', '-j8', scons_option, 'stage_install',
        "installdir=${stagedInstallDir}")
}


task openGeePostGisRpm(type: GeeRpm) {
    mustRunAfter stageOpenGeeInstall

    packageName = 'opengee-postgis'
    release = ospackage.release
    version = '2.3.9'
    user = 'root'
    permissionGroup = 'root'
    packageGroup = 'Application/Productivity'
    summary = 'Post GIS extension for Postgre SQL server used by Open GEE'
    packageDescription = 'Post GIS extension for Postgre SQL server used by Open GEE'
    license = 'GPLv2'
    url = 'https://github.com/google/earthenterprise/tree/master/earth_enterprise/third_party/postgis'
    type = BINARY
    autoFindProvides = true
    autoFindRequires = true

    // "requires" is for runtime dependencies. "requiresPre" is for pre-install
    // script dependencies. We need both because pre- and post-install scripts
    // call Open GEE binaries, and they may fail if a different version of
    // common libraries is installed.
    // In this case, opengee-postgis doesn't have a pre- or post-install script
    // to worry about, but we do need to make sure that opengee-common's
    // pre-install script runs first.
    requires('opengee-common', ospackage.version, GREATER | EQUAL)
    requiresPre('opengee-common', ospackage.version, GREATER | EQUAL)

    // The code in GeeRpm decides that this RPM should depend on proj, but
    // it actually depends on proj-devel.
    requires('proj-devel')

    from (stagedInstallDir_postgis_opt) {
        into new File(packageInstallRootDir, 'opt')
    }

    from (new File(stagedInstallDir_server_opt, 'google/lib')) {
        // Include libpq, since it's used by postgis command-line utilities:
        include 'libpq.*'

        into packageInstallLibDir
    }
}

task openGeePostGisDeb(type: GeeDeb) {
    mustRunAfter stageOpenGeeInstall

    packageName = openGeePostGisRpm.packageName
    release = "${findBuildNumber()}"
    version = openGeePostGisRpm.version
    user = openGeePostGisRpm.user
    permissionGroup = openGeePostGisRpm.permissionGroup
    packageGroup = 'misc'
    summary = openGeePostGisRpm.summary
    packageDescription = openGeePostGisRpm.packageDescription
    license = openGeePostGisRpm.license
    url = openGeePostGisRpm.url
    type = BINARY

    requires('opengee-common', ospackage.version, GREATER | EQUAL)
    requires('proj-devel')

    from (stagedInstallDir_postgis_opt) {
        into new File(packageInstallRootDir, 'opt')
    }

    from (new File(stagedInstallDir_server_opt, 'google/lib')) {
        // Include libpq, since it's used by postgis command-line utilities:
        include 'libpq.*'

        into packageInstallLibDir
    }
}

if (project.hasProperty('buildOpenGee')) {
    openGeePostGisRpm.dependsOn stageOpenGeeInstall
    openGeePostGisDeb.dependsOn stageOpenGeeInstall
}

// Expands the `gevars.sh.template` and any other templates so they can be
// used in the `common` package, and prefixed to install scripts for all the
// various packages.
task openGeeSharedFiles(type: Copy) {
    from file('shared/src')
    into file('build/shared')

    CopySpecTemplates.expand(delegate,
        [
            'openGeeVersion': ospackage.version
        ])
}

task openGeeCommonInitScripts(type: Copy, dependsOn: openGeeSharedFiles) {
    from(file('opengee-common/src'))
    into "${buildDir}/opengee-common"

    CopySpecTemplates.expand(delegate, [
            'openGeeVersion': ospackage.version,
            'project': project
        ])
}

task openGeeCommonRpm(type: GeeRpm, dependsOn: openGeeCommonInitScripts) {
    mustRunAfter stageOpenGeeInstall

    packageName = 'opengee-common'
    version = ospackage.version
    release = ospackage.release
    user = 'root'
    permissionGroup = 'root'
    packageGroup = 'Application/Productivity'
    summary = 'Shared Open GEE code and third-party libraries bundled with Open GEE'
    packageDescription =
'''Currently this package includes:

* MesaLib: LGPL 2.1
* PIL (Python Imaging Library): Python Imaging Library 1.1.7
* Apache: Apache 2.0
* apr-util: Apache 2.0
* apr: Apache 2.0
* Firefox: MPL 1.1
* GDAL: MIT
* libcurl: MIT/X
* libjs: MPL 1.1
* mgrs: mgrs 1.1.0
* mm: mm 1.4.2
* mod_wsgi: Apache 2.0
* Open JPEG: Open JPEG BSD 2.1.2
* Open LDAP: OpenLDAP Public License 2.8
* Open SSL: Open SSL 1.0.2h
* PCRE: BSD
* Postgre SQL: BSD
* Psycopg2: Psycopg2 GPL 3+ v. 2.4.6
* Python: PSF 2
* Qt: GPL 2+, QPL 1
* Setup Tools: PSF 2 or ZPL
* Skia: Skia 5.1.2
* Tornado: Apache 2.0
* Various Open GEE Libraries
'''
    license =
        'ASL 2.0 and ' +
        'BSD and ' +
        'GPLv2+ and ' +
        'Psycopg2 GPL 3+ and ' +
        'LGPLv2 and ' +
        'MIT and ' +
        'MPLv1.1 and ' +
        'PSF 2 and ' +
        'Python Imaging Library 1.1.7 and ' +
        'mgrs 1.1.0 and mm 1.4.2 and ' +
        'OpenLDAP and ' +
        'OpenSSL and ' +
        'Skia 5.1.2'
 
    type = BINARY
    autoFindProvides = true
    autoFindRequires = true

    // When the scons release=1 package target is run as a non-root user,
    // scons does not include /sbin in the path, so auto-detection of
    // chkconfig fails, so this dependency is explicit.
    requires('chkconfig')
    requires('shadow-utils')

    if ("${findBuildNumber()}.${rpmPlatformString}".contains('el6')) {
        requires('python27')
        requires('python27-lxml')
    }

    requiresCommands(packageSharedCommands +
        ['cat', 'cut', 'getent', 'grep'])

    autoFindRequiresFilter = rpmCapabilityFilter

    // Don't specify install scripts as single files.  It doesn't work for
    // RPMs:
    preInstall = file("${buildDir}/opengee-common/pre-install.sh")
    postUninstall = file("${buildDir}/opengee-common/post-uninstall.sh")

    from (file('build/shared/gevars.sh')) {
        into new File(packageInstallRootDir, 'etc/init.d')
    }

    from (stagedInstallDir_common_opt) {
        into new File(packageInstallRootDir, 'opt')

        // Included in opengee-extra
        exclude '**/doc'
        exclude '**/man'
        exclude '**/Readme.txt'
        exclude '**/gehttpd/examples'
        exclude 'google/lib/openjpeg-2.3' // Contains makefiles - not needed for production
        exclude '**/protobuf/internal/*test*.py'
    }

    from (stagedInstallDir_common_user_magic) {
        into packageInstallRootDir

        // Included in opengee-extra
        exclude '**/ldap.conf.default'
    }

    from(file('opengee-common/src/install')) {
        into packageInstallRootDir
    }
}

task openGeeCommonDeb (type: GeeDeb, dependsOn: openGeeCommonInitScripts) {
    mustRunAfter stageOpenGeeInstall

    packageName = openGeeCommonRpm.packageName
    version = ospackage.version
    release = ospackage.release
    user = openGeeCommonRpm.user
    permissionGroup = openGeeCommonRpm.permissionGroup
    packageGroup = 'misc'
    summary = openGeeCommonRpm.summary
    packageDescription = openGeeCommonRpm.packageDescription
    license = openGeeCommonRpm.license
    priority = 'optional'

    requires('flex')
    requires('freeglut3')
    requires('gettext')
    requires('libc6')
    requires('libfreetype6')
    requires('libperl4-corelibs-perl')
    requires('libpng12-0')
    requires('libstdc++6')
    requires('libtool')
    requires('libxml2-utils')
    requires('python-imaging')
    requires('python-lxml')
    requires('python-psycopg2')
    requires('python-setuptools')
    requires('python2.7')

    // Use single files for install scripts.  Othewrise, OS Package wraps the
    // code in extra statements.
    preInstallFile file("${buildDir}/opengee-common/pre-install.sh")
    postUninstallFile file("${buildDir}/opengee-common/post-uninstall.sh")

    from (file('build/shared/gevars.sh')) {
        into new File(packageInstallRootDir, 'etc/init.d')
    }

    from (stagedInstallDir_common_opt) {
        into new File(packageInstallRootDir, 'opt')

        // Included in opengee-extra
        exclude '**/doc'
        exclude '**/man'
        exclude '**/Readme.txt'
        exclude '**/gehttpd/examples'
        exclude 'google/lib/openjpeg-2.3' // Contains makefiles - not needed for production
        exclude '**/protobuf/internal/*test*.py'
    }

    from (stagedInstallDir_common_user_magic) {
        into packageInstallRootDir

        // Included in opengee-extra
        exclude '**/ldap.conf.default'
    }

    from(file('opengee-common/src/install')) {
        into packageInstallRootDir
    }
}

if (project.hasProperty('buildOpenGee')) {
    openGeeCommonRpm.dependsOn stageOpenGeeInstall
    openGeeCommonDeb.dependsOn stageOpenGeeInstall
}

task openGeeServerInitScripts(type: Copy, dependsOn: openGeeSharedFiles) {
    from(file('opengee-server/src'))
    into "${buildDir}/opengee-server"

    CopySpecTemplates.expand(delegate, [
            'openGeeVersion': ospackage.version,
            'stagedInstallDir_server_opt': stagedInstallDir_server_opt,
            'project': project
        ])
}

task openGeeServerRpm(type: GeeRpm, dependsOn: openGeeServerInitScripts) {
    mustRunAfter stageOpenGeeInstall

    packageName = 'opengee-server'
    version = ospackage.version
    release = ospackage.release
    user = 'root'
    permissionGroup = 'root'
    packageGroup = 'Application/Productivity'
    summary = 'Open Google Earth Enterprise 3D globe and 2D map tile server'
    packageDescription =
        'OpenGEE Server Daemons (Apache, PostGRE SQL) and command-line tools.'
    license = 'ASL 2.0'
    url = 'https://github.com/google/earthenterprise'
    autoFindProvides = true
    autoFindRequires = true

    // "requires" is for runtime dependencies. "requiresPre" is for pre-install
    // script dependencies. We need both because pre- and post-install scripts
    // call Open GEE binaries, and they may fail if a different version of
    // common libraries is installed.
    requires('opengee-common', ospackage.version, GREATER | EQUAL)
    requiresPre('opengee-common', ospackage.version, GREATER | EQUAL)
    requires('opengee-postgis', '2.3.9', GREATER | EQUAL)
    requiresPre('opengee-postgis', '2.3.9', GREATER | EQUAL)
    conflicts('opengee-postgis', '2.0', LESS )
    conflicts('opengee-postgis', '2.4', GREATER | EQUAL)
    requires('python-unittest2')
    // The WMS Service requires PIL, which is not automatically detected:
    requires('python-imaging')
    requires('python-lxml')

    requiresCommands(
        packageSharedCommands +
        [
            // Install script commands:
            'cat', 'chmod', 'chown', 'cut', 'find', 'getent', 'mkdir', 'python',
            'sed', 'su', 'sudo'
        ]
    )

    autoFindRequiresFilter = rpmCapabilityFilter
    requiresCommandFilter = rpmCommandFilter

    // Don't specify install scripts as single files.  It doesn't work for
    // RPMs:
    preInstall = file("${buildDir}/opengee-server/pre-install.sh")
    postInstall = file("${buildDir}/opengee-server/post-install.sh")
    preUninstall = file("${buildDir}/opengee-server/pre-uninstall.sh")
    postUninstall = file("${buildDir}/opengee-server/post-uninstall.sh")

    directory('/opt/google/install', 0700)
    directory('/opt/google/gehttpd/logs', 0755)
    directory('/var/opt/google/run', 0775)
    directory('/var/opt/google/log', 0775)
    directory('/var/opt/google/pgsql', 0700)
    directory('/var/opt/google/pgsql/logs')

    filesMatching(
        '/etc/init.d/geserver')
    {
        it.mode = 0755
    }

    // since these are "sourced" they cannot be exec...
    filesMatching(
        '/etc/profile.d/ge-server.csh')
    {
        it.mode = 0644
    }
    filesMatching(
        '/etc/profile.d/ge-server.sh')
    {
        it.mode = 0644
    }

    from(stagedInstallDir_server_opt) {
        // libpq is in the opengee-postgis package:
        exclude 'google/lib/libpq.*'

        // Included in opengee-extra
        exclude '**/manual'
        exclude '**/search/plugin/example*'
        exclude '**/search/plugin/custom*'
        exclude '**/maps/example*'
        exclude '**/original'
        exclude '**/ExampleSearch.conf'
        exclude '**/doc'
        exclude '**/mod_wsgi-ge-extra.conf'
        exclude '**/examplesearch.sql'
        exclude '**/examplesearch_delete.sql'
        exclude '**/readme.txt'

        into new File(packageInstallRootDir, 'opt')
    }

    from(stagedInstallDir_server_etc) {
        into new File(packageInstallRootDir, 'etc')
    }

    from(stagedInstallDir_server_user_magic) {
        into packageInstallRootDir
    }

    from(stagedInstallDir_server_geplaces) {
        into new File(packageInstallRootDir, 'opt/google/share/geplaces')
    }

    // Create links
    link('/opt/google/etc', '/etc/opt/google')
    link('/opt/google/log', '/var/opt/google/log')
    link('/opt/google/run', '/var/opt/google/run')
}

task openGeeServerDeb (type: GeeDeb, dependsOn: openGeeServerInitScripts) {
    mustRunAfter stageOpenGeeInstall

    packageName = openGeeServerRpm.packageName
    version = ospackage.version
    release = ospackage.release
    user = openGeeServerRpm.user
    permissionGroup = openGeeServerRpm.permissionGroup
    packageGroup = 'misc'
    summary = openGeeServerRpm.summary
    packageDescription = openGeeServerRpm.packageDescription
    license = openGeeServerRpm.license
    url = openGeeServerRpm.url

    requires('opengee-common', ospackage.version, GREATER | EQUAL)
    requires('opengee-postgis', '2.3.9', GREATER | EQUAL)
    conflicts('opengee-postgis', '2.0', LESS )
    conflicts('opengee-postgis', '2.4', GREATER | EQUAL)
    requires('python-unittest2')
    // The WMS Service requires PIL, which is not automatically detected:
    requires('python-imaging')
    requires('python-lxml')

    requiresCommands(
        packageSharedCommands +
        [
            // Install script commands:
            'cat', 'chmod', 'chown', 'cut', 'find', 'getent', 'mkdir', 'python',
            'sed', 'su', 'sudo'
        ]
    )

    // Specify a single file for each install script.  Otherwise, OSPackage
    // wraps the code in extra statements that, e.g., only run the
    // post-install script on a new install, and not on upgrade:
    preInstallFile file("${buildDir}/opengee-server/pre-install.sh")
    postInstallFile file("${buildDir}/opengee-server/post-install.sh")
    preUninstallFile file("${buildDir}/opengee-server/pre-uninstall.sh")
    postUninstallFile file("${buildDir}/opengee-server/post-uninstall.sh")

    directory('/opt/google/install', 0700)
    directory('/opt/google/gehttpd/logs', 0755)
    directory('/var/opt/google/run', 0775)
    directory('/var/opt/google/log', 0775)
    directory('/var/opt/google/pgsql', 0700)
    directory('/var/opt/google/pgsql/logs')

    filesMatching(
        '/etc/init.d/geserver')
    {
        it.mode = 0755
    }

    // since these are "sourced" they cannot be exec...
    filesMatching(
        '/etc/profile.d/ge-server.csh')
    {
        it.mode = 0644
    }
    filesMatching(
        '/etc/profile.d/ge-server.sh')
    {
        it.mode = 0644
    }

    from(stagedInstallDir_server_opt) {
        // libpq is in the opengee-postgis package:
        exclude 'google/lib/libpq.*'

        // Included in opengee-extra
        exclude '**/manual'
        exclude '**/search/plugin/example*'
        exclude '**/search/plugin/custom*'
        exclude '**/maps/example*'
        exclude '**/original'
        exclude '**/ExampleSearch.conf'
        exclude '**/doc'
        exclude '**/mod_wsgi-ge-extra.conf'
        exclude '**/examplesearch.sql'
        exclude '**/examplesearch_delete.sql'
        exclude '**/readme.txt'

        into new File(packageInstallRootDir, 'opt')
    }

    from(stagedInstallDir_server_etc) {
        into new File(packageInstallRootDir, 'etc')
    }

    from(stagedInstallDir_server_user_magic) {
        into packageInstallRootDir
    }

    from(stagedInstallDir_server_geplaces) {
        into new File(packageInstallRootDir, 'opt/google/share/geplaces')
    }

    // Create links
    link('/opt/google/etc', '/etc/opt/google')
    link('/opt/google/log', '/var/opt/google/log')
    link('/opt/google/run', '/var/opt/google/run')
}

if (project.hasProperty('buildOpenGee')) {
    openGeeServerRpm.dependsOn stageOpenGeeInstall
    openGeeServerDeb.dependsOn stageOpenGeeInstall
}


task openGeeFusionInitScripts(type: Copy, dependsOn: openGeeSharedFiles) {
    from(file('opengee-fusion/src'))
    into "${buildDir}/opengee-fusion"

    CopySpecTemplates.expand(delegate, [
            'openGeeVersion': ospackage.version,
            'project': project
        ])
}


task openGeeFusionRpm (type: GeeRpm, dependsOn: openGeeFusionInitScripts) {
    mustRunAfter stageOpenGeeInstall

    packageName = 'opengee-fusion'
    version = ospackage.version
    release = ospackage.release
    user = 'root'
    permissionGroup = 'root'
    packageGroup = 'Application/Productivity'
    summary = 'Open GEE Fusion UI and Command-line Utilities'
    packageDescription =
'''Command line utitiles and Qt UI for building Open GEE globes.

The utilities in this package allow Open GEE globe and map databases to be
built from raster, vector, and location properties data.
'''
    license = 'ASL 2.0'
    url = 'https://github.com/google/earthenterprise'
    type = BINARY
    autoFindProvides = true
    autoFindRequires = true

    // "requires" is for runtime dependencies. "requiresPre" is for pre-install
    // script dependencies. We need both because pre- and post-install scripts
    // call Open GEE binaries, and they may fail if a different version of
    // common libraries is installed.
    requires('opengee-common', ospackage.version, GREATER | EQUAL)
    requiresPre('opengee-common', ospackage.version, GREATER | EQUAL)
    requires('proj-devel') /* This dependency is not being picked up automatically by GeeRpm task */
    requires('/etc/rc.d/init.d/functions')
    requiresCommands(
        packageSharedCommands +
        [
            // Install script commands:
            'cat', 'chcon', 'chmod', 'chown', 'cut', 'daemonize', 'df',
            'dirname', 'expr', 'find', 'getent', 'grep', 'hostname', 'mkdir',
            'nproc', 'tr'
        ]
    )

    // Don't specify install scripts as single files.  It doesn't work for
    // RPMs:
    preInstall = file("${buildDir}/opengee-fusion/pre-install.sh")
    postInstall = file("${buildDir}/opengee-fusion/post-install.sh")
    preUninstall = file("${buildDir}/opengee-fusion/pre-uninstall.sh")
    postUninstall = file("${buildDir}/opengee-fusion/post-uninstall.sh")

    directory('/var/opt/google/run', 0775)
    directory('/var/opt/google/log', 0775)

    filesMatching(
        '/etc/init.d/gefusion'
    ) {
        it.mode = 0755
    }

    // since these are "sourced" they cannot be exec...
    filesMatching(
        '/etc/profile.d/ge-fusion.csh'
    ) {
        it.mode = 0644
    }
    filesMatching(
        '/etc/profile.d/ge-fusion.sh'
    ) {
        it.mode = 0644
    }

    from(stagedInstallDir_fusion) {
        into packageInstallRootDir

        // Included in opengee-extra
        exclude '**/doc'
        exclude '**/taskrules'
    }

    from(file('opengee-fusion/src/install')) {
        into packageInstallRootDir

        CopySpecTemplates.expand(delegate, [
                'openGeeVersion': ospackage.version
            ])
    }

    // Create links
    link('/opt/google/etc', '/etc/opt/google')
    link('/opt/google/log', '/var/opt/google/log')
    link('/opt/google/run', '/var/opt/google/run')
}

task openGeeFusionDeb (type: GeeDeb, dependsOn: openGeeFusionInitScripts) {
    mustRunAfter stageOpenGeeInstall

    packageName = openGeeFusionRpm.packageName
    version = ospackage.version
    release = ospackage.release
    user = openGeeFusionRpm.user
    permissionGroup = openGeeFusionRpm.permissionGroup
    packageGroup = 'misc'
    summary = openGeeFusionRpm.summary
    packageDescription = openGeeFusionRpm.packageDescription
    license = openGeeFusionRpm.license
    url = openGeeFusionRpm.url
    type = BINARY

    requires('opengee-common', ospackage.version, GREATER | EQUAL)
    requires('dpkg')
    requires('lsb-base')

    // Specify a single file for each install script.  Otherwise, OSPackage
    // wraps the code in extra statements that, e.g., only run the
    // post-install script on a new install, and not on upgrade:
    preInstallFile file("${buildDir}/opengee-fusion/pre-install.sh")
    postInstallFile file("${buildDir}/opengee-fusion/post-install.sh")
    preUninstallFile file("${buildDir}/opengee-fusion/pre-uninstall.sh")
    postUninstallFile file("${buildDir}/opengee-fusion/post-uninstall.sh")

    directory('/var/opt/google/run', 0775)
    directory('/var/opt/google/log', 0775)

    filesMatching(
        '/etc/init.d/gefusion'
    ) {
        it.mode = 0755
    }

    // since these are "sourced" they cannot be exec...
    filesMatching(
        '/etc/profile.d/ge-fusion.csh'
    ) {
        it.mode = 0644
    }
    filesMatching(
        '/etc/profile.d/ge-fusion.sh'
    ) {
        it.mode = 0644
    }

    from(stagedInstallDir_fusion) {
        into packageInstallRootDir

        // Included in opengee-extra
        exclude '**/doc'
        exclude '**/taskrules'
    }

    from(file('opengee-fusion/src/install')) {
        into packageInstallRootDir

        CopySpecTemplates.expand(delegate, [
                'openGeeVersion': ospackage.version
            ])
    }

    // Create links
    link('/opt/google/etc', '/etc/opt/google')
    link('/opt/google/log', '/var/opt/google/log')
    link('/opt/google/run', '/var/opt/google/run')
}

if (project.hasProperty('buildOpenGee')) {
    openGeeFusionRpm.dependsOn stageOpenGeeInstall
    openGeeFusionDeb.dependsOn stageOpenGeeInstall
}

task openGeeExtraInitScripts(type: Copy, dependsOn: openGeeSharedFiles) {
    from(file('opengee-extra/src'))
    into "${buildDir}/opengee-extra"

    CopySpecTemplates.expand(delegate, [
            'openGeeVersion': ospackage.version,
            'openGeeRelease': ospackage.release,
            'project': project
        ])
}

task openGeeExtraRpm(type: GeeRpm, dependsOn: openGeeExtraInitScripts) {
    mustRunAfter stageOpenGeeInstall

    packageName = 'opengee-extra'
    version = ospackage.version
    release = ospackage.release
    user = 'root'
    permissionGroup = 'root'
    packageGroup = 'Application/Productivity'
    summary = 'Documentation, samples, examples, and tutorials for Open Google Earth Enterprise'
    packageDescription =
        'Documentation, samples, examples, and tutorials for Open Google Earth Enterprise'
    license = 'ASL 2.0'
    url = 'https://github.com/google/earthenterprise'
    autoFindProvides = true
    autoFindRequires = true

    autoFindRequiresFilter = rpmCapabilityFilter
    requiresCommandFilter = rpmCommandFilter

    // This package contains files that were in opengee-server and
    // opengee-fusion in versions 5.3.4.1 and before.
    conflicts('opengee-server', "5.3.4.1", LESS | EQUAL)
    conflicts('opengee-fusion', "5.3.4.1", LESS | EQUAL)

    postInstall = file("${buildDir}/opengee-extra/post-install.sh")
    preUninstall = file("${buildDir}/opengee-extra/pre-uninstall.sh")

    // -----------------------------------------------------------------------
    // Common Extras
    // -----------------------------------------------------------------------

    from (stagedInstallDir_common_opt) {
        into new File(packageInstallRootDir, 'opt')
        include '**/doc/**'
        include '**/man/**'
        include '**/Readme.txt'
        include '**/gehttpd/examples/**'
    }

    from(stagedInstallDir_manual) {
        into packageInstallRootDir
    }

    from (stagedInstallDir_common_user_magic) {
        into packageInstallRootDir
        include '**/ldap.conf.default'
    }

    filesMatching(
        '/opt/google/share/searchexample/searchexample'
    ) {
        it.mode = 0755
    }


    // -----------------------------------------------------------------------
    // Server Extras
    // -----------------------------------------------------------------------

    from(stagedInstallDir_server_opt) {
        include '**/manual/**'
        include '**/search/plugin/example*'
        include '**/search/plugin/custom*'
        include '**/maps/example*'
        include '**/original/**'
        include '**/ExampleSearch.conf'
        include '**/doc/**'
        include '**/mod_wsgi-ge-extra.conf'
        include '**/examplesearch.sql'
        include '**/examplesearch_delete.sql'
        include '**/readme.txt'

        into new File(packageInstallRootDir, 'opt')
    }

    from(stagedInstallDir_server_searchexample) {
        into new File(packageInstallRootDir, 'opt/google/share/searchexample')
    }

    link('/opt/google/gehttpd/htdocs/shared_assets/docs', '/opt/google/share/doc')

    // -----------------------------------------------------------------------
    // Fusion Extras
    // -----------------------------------------------------------------------

    directory('/opt/google/share/tutorials', 0755)

    from(stagedInstallDir_fusion) {
        into packageInstallRootDir
        include '**/doc/**'
        include '**/taskrules/**'
    }

    from(stagedInstallDir_tutorial) {
        into packageInstallRootDir
    }

    filesMatching(
        '/opt/google/share/tutorials/fusion/download_tutorial.sh'
    ) {
        it.mode = 0755
    }
}

task openGeeExtraDeb(type: GeeDeb, dependsOn: openGeeExtraInitScripts) {
    mustRunAfter stageOpenGeeInstall

    packageName = openGeeExtraRpm.packageName
    version = ospackage.version
    release = ospackage.release
    user = openGeeExtraRpm.user
    permissionGroup = openGeeExtraRpm.permissionGroup
    packageGroup = openGeeExtraRpm.packageGroup
    summary = openGeeExtraRpm.summary
    packageDescription = openGeeExtraRpm.packageDescription
    license = openGeeExtraRpm.license
    url = openGeeExtraRpm.url

    // This package contains files that were in opengee-server and
    // opengee-fusion in versions 5.3.4.1 and before.
    conflicts('opengee-server', "5.3.4.1", LESS | EQUAL)
    conflicts('opengee-fusion', "5.3.4.1", LESS | EQUAL)

    postInstallFile file("${buildDir}/opengee-extra/post-install.sh")
    preUninstallFile file("${buildDir}/opengee-extra/pre-uninstall.sh")

    // -----------------------------------------------------------------------
    // Common Extras
    // -----------------------------------------------------------------------

    from (stagedInstallDir_common_opt) {
        into new File(packageInstallRootDir, 'opt')
        include '**/doc/**'
        include '**/man/**'
        include '**/Readme.txt'
        include '**/gehttpd/examples/**'
    }

    from(stagedInstallDir_manual) {
        into packageInstallRootDir
    }

    from (stagedInstallDir_common_user_magic) {
        into packageInstallRootDir
        include '**/ldap.conf.default'
    }

    filesMatching(
        '/opt/google/share/searchexample/searchexample'
    ) {
        it.mode = 0755
    }


    // -----------------------------------------------------------------------
    // Server Extras
    // -----------------------------------------------------------------------

    from(stagedInstallDir_server_opt) {
        include '**/manual/**'
        include '**/search/plugin/example*'
        include '**/search/plugin/custom*'
        include '**/maps/example*'
        include '**/original/**'
        include '**/ExampleSearch.conf'
        include '**/doc/**'
        include '**/mod_wsgi-ge-extra.conf'
        include '**/examplesearch.sql'
        include '**/examplesearch_delete.sql'
        include '**/readme.txt'

        into new File(packageInstallRootDir, 'opt')
    }

    from(stagedInstallDir_server_searchexample) {
        into new File(packageInstallRootDir, 'opt/google/share/searchexample')
    }

    link('/opt/google/gehttpd/htdocs/shared_assets/docs', '/opt/google/share/doc')

    // -----------------------------------------------------------------------
    // Fusion Extras
    // -----------------------------------------------------------------------

    directory('/opt/google/share/tutorials', 0755)

    from(stagedInstallDir_fusion) {
        into packageInstallRootDir
        include '**/doc/**'
        include '**/taskrules/**'
    }

    from(stagedInstallDir_tutorial) {
        into packageInstallRootDir
    }

    filesMatching(
        '/opt/google/share/tutorials/fusion/download_tutorial.sh'
    ) {
        it.mode = 0755
    }
}

if (project.hasProperty('buildOpenGee')) {
    openGeeExtraRpm.dependsOn stageOpenGeeInstall
    openGeeExtraDeb.dependsOn stageOpenGeeInstall
}

// Convenience package that installs opengee-server + opengee-extra
task openGeeFullServerRpm (type: GeeRpm) {
    mustRunAfter stageOpenGeeInstall

    packageName = 'opengee-full-server'
    version = ospackage.version
    release = ospackage.release
    user = 'root'
    permissionGroup = 'root'
    packageGroup = 'Application/Productivity'
    summary = 'Full Open Google Earth Enterprise 3D globe and 2D map tile server'
    packageDescription =
        'Full install of the OpenGEE Server Daemons (Apache, PostGRE SQL) and command-line tools.'

    license = 'ASL 2.0'
    url = 'https://github.com/google/earthenterprise'
    type = BINARY
    autoFindProvides = true
    autoFindRequires = true

    requires('opengee-server', ospackage.version, GREATER | EQUAL)
    requires('opengee-extra', ospackage.version, GREATER | EQUAL)
}

task openGeeFullServerDeb (type: GeeDeb) {
    mustRunAfter stageOpenGeeInstall

    packageName = openGeeFullServerRpm.packageName
    version = ospackage.version
    release = ospackage.release
    user = openGeeFullServerRpm.user
    permissionGroup = openGeeFullServerRpm.permissionGroup
    packageGroup = openGeeFullServerRpm.packageGroup
    summary = openGeeFullServerRpm.summary
    packageDescription = openGeeFullServerRpm.packageDescription
    license = openGeeFullServerRpm.license
    url = openGeeFullServerRpm.url
    type = BINARY

    requires('opengee-server', ospackage.version, GREATER | EQUAL)
    requires('opengee-extra', ospackage.version, GREATER | EQUAL)
}

if (project.hasProperty('buildOpenGee')) {
    openGeeFullServerRpm.dependsOn stageOpenGeeInstall
    openGeeFullServerDeb.dependsOn stageOpenGeeInstall
}

// Convenience package that installs opengee-fusion + opengee-extra
task openGeeFullFusionRpm (type: GeeRpm) {
    mustRunAfter stageOpenGeeInstall

    packageName = 'opengee-full-fusion'
    version = ospackage.version
    release = ospackage.release
    user = 'root'
    permissionGroup = 'root'
    packageGroup = 'Application/Productivity'
    summary = 'Full Open GEE Fusion UI and Command-line Utilities'
    packageDescription ='Full install of the Open GEE Fusion UI and Command-line Utilities'

    license = 'ASL 2.0'
    url = 'https://github.com/google/earthenterprise'
    type = BINARY
    autoFindProvides = true
    autoFindRequires = true

    requires('opengee-fusion', ospackage.version, GREATER | EQUAL)
    requires('opengee-extra', ospackage.version, GREATER | EQUAL)
}

task openGeeFullFusionDeb (type: GeeDeb) {
    mustRunAfter stageOpenGeeInstall

    packageName = openGeeFullFusionRpm.packageName
    version = ospackage.version
    release = ospackage.release
    user = openGeeFullFusionRpm.user
    permissionGroup = openGeeFullFusionRpm.permissionGroup
    packageGroup = openGeeFullFusionRpm.packageGroup
    summary = openGeeFullFusionRpm.summary
    packageDescription = openGeeFullFusionRpm.packageDescription
    license = openGeeFullFusionRpm.license
    url = openGeeFullFusionRpm.url
    type = BINARY

    requires('opengee-fusion', ospackage.version, GREATER | EQUAL)
    requires('opengee-extra', ospackage.version, GREATER | EQUAL)
}

if (project.hasProperty('buildOpenGee')) {
    openGeeFullFusionRpm.dependsOn stageOpenGeeInstall
    openGeeFullFusionDeb.dependsOn stageOpenGeeInstall
}

task openGeeRpms(
    dependsOn: [
        'openGeeServerRpm', 'openGeeFullServerRpm',
        'openGeeFusionRpm', 'openGeeFullFusionRpm',
        'openGeeCommonRpm', 'openGeePostGisRpm', 'openGeeExtraRpm'
    ])

task openGeeDebs(
    dependsOn: [
        'openGeeServerDeb', 'openGeeFullServerDeb',
        'openGeeFusionDeb', 'openGeeFullFusionDeb',
        'openGeeCommonDeb', 'openGeePostGisDeb', 'openGeeExtraDeb'
    ])

task osPackage(dependsOn: org.opengee.os.Platform.osId == 'ubuntu' ? openGeeDebs : openGeeRpms) {
    group = 'Packaging'
    description = "Build ${org.opengee.os.Platform.osId == 'ubuntu' ? 'Deb' : 'RPM'} packages from on OpenGEE staged install."
}
