# Install MoinMoin.
#
class wiki::moin {

    if !$moin_package {
        if $moin_package_latest {
            $moin_package = $moin_package_latest
        } else {
            fail("Must define \$moin_package or \$moin_package_latest")
        }
    }

    $moin_patch = regsubst($moin_package, '\.tar\.gz', '.patch')

    file { "/usr/local/src/moin.tar.gz":
        ensure => present,
        mode   => "0644",
        owner  => "root",
        group  => "root",
        source => "puppet:///files/packages/${moin_package}",
    }
    file { "/usr/local/src/moin.patch":
        ensure => present,
        mode   => "0644",
        owner  => "root",
        group  => "root",
        source => "puppet:///files/packages/${moin_patch}",
    }
    util::extract::tar { "/usr/local/src/moin":
        ensure  => latest,
        strip   => 1,
        source  => "/usr/local/src/moin.tar.gz",
        require => File["/usr/local/src/moin.tar.gz"],
    }
    util::patch { "/usr/local/src/moin":
        source  => "/usr/local/src/moin.patch",
        require => Util::Extract::Tar["/usr/local/src/moin"],
    }
    if $moin_package =~ /^moin-1\.9/ {
        exec { "moin-copy-htdocs":
            user    => "root",
            path    => "/bin:/usr/bin:/sbin:/usr/sbin",
            command => "cp -a /usr/local/src/moin/MoinMoin/web/static/htdocs /usr/local/src/moin/wiki",
            creates => "/usr/local/src/moin/wiki/htdocs",
            require => Util::Patch["/usr/local/src/moin"],
            before  => Python::Setup::Install["/usr/local/src/moin"],
        }
    }
    python::setup::install { "/usr/local/src/moin":
        require => Util::Patch["/usr/local/src/moin"],
    }

    $shared = $::operatingsystem ? {
        "ubuntu" => "/usr/local/share/moin",
        default  => "/usr/share/moin",
    }

    file { "${shared}/htdocs/.htaccess":
        ensure  => present,
        mode    => "0644",
        owner   => "root",
        group   => "root",
        content => "SetHandler None\n",
        require => Python::Setup::Install["/usr/local/src/moin"],
    }

}


# Fetch graphingwiki from svn.
#
class wiki::graphingwiki::common {

    if !$graphingwiki_package {
        if $graphingwiki_package_latest {
            $graphingwiki_package = $graphingwiki_package_latest
        } else {
            fail("Must define \$graphingwiki_package or \$graphingwiki_package_latest")
        }
    }

    file { "/usr/local/src/graphingwiki.tar.gz":
        ensure => directory,
        mode   => "0644",
        owner  => "root",
        group  => $::operatingsystem ? {
            "openbsd" => "wheel",
            default   => "root",
        },
        source => "puppet:///files/packages/${graphingwiki_package}",
    }
    util::extract::tar { "/usr/local/src/graphingwiki":
        ensure  => latest,
        strip   => 1,
        source  => "/usr/local/src/graphingwiki.tar.gz",
        require => File["/usr/local/src/graphingwiki.tar.gz"],
    }

}


# Install Graphingwiki.
#
class wiki::graphingwiki inherits wiki::graphingwiki::common {

    python::setup::install { "/usr/local/src/graphingwiki/graphingwiki":
        require => Util::Extract::Tar["/usr/local/src/graphingwiki"],
    }

}


# Install Opencollab.
#
class wiki::opencollab inherits wiki::graphingwiki::common {

    python::setup::install { "/usr/local/src/graphingwiki/opencollab":
        require => Util::Extract::Tar["/usr/local/src/graphingwiki"],
    }

}


# Install collab.
#
class wiki::collab inherits wiki::graphingwiki::common {

    python::setup::install { "/usr/local/src/graphingwiki/collab":
        require => Util::Extract::Tar["/usr/local/src/graphingwiki"],
    }

}


# Configure collab server.
#
# === Global variables
#
#   $wiki_datadir:
#       Directory for wiki data. Defaults to /srv/wikis.
#
#   $collab_webhosts:
#       List of collab virtual hosts.
#
#   $collab_webroot:
#       Path to collab in webserver document root.
#       Defaults to "/srv/www/https/*/collab".
#
#   $collab_jabberdomain:
#       Domain for jabber extauth.
#
#   $collab_conferencedomain:
#       Conference domain for jabber extauth.
#       Defaults to conference.$wiki_collab_jabberdomain.
#
class wiki::collab::base {

    include cairo::python
    include igraph::python
    include graphviz::python
    include ldap::client::python

    include apache::sslserver
    include apache::mod::authnz_ldap
    include apache::mod::ldap
    include apache::mod::rewrite
    include apache::mod::wsgi

    include wiki::moin
    include wiki::graphingwiki
    include wiki::opencollab
    include wiki::collab

    include user::system
    realize(User["collab"], Group["collab"])

    exec { "usermod-www-data":
        path    => "/bin:/usr/bin:/sbin:/usr/sbin",
        command => "usermod -a -G collab ${apache::sslserver::user}",
        unless  => "id -n -G ${apache::sslserver::user} | grep '\\bcollab\\b'",
        require => Group["collab"],
    }

    if $wiki_datadir {
        file { $wiki_datadir:
            ensure  => directory,
            mode    => "0755",
            owner   => "root",
            group   => "root",
            seltype => "httpd_sys_rw_content_t",
        }
        selinux::manage_fcontext { "${wiki_datadir}(/.*)?":
            type   => "httpd_sys_rw_content_t",
            before => File[$wiki_datadir],
        }
        file { "/srv/wikis":
            ensure  => link,
            target  => $wiki_datadir,
            seltype => "httpd_sys_rw_content_t",
            require => File[$wiki_datadir],
        }
    } else {
        file { "/srv/wikis":
            ensure  => directory,
            mode    => "0755",
            owner   => "root",
            group   => "root",
            seltype => "httpd_sys_rw_content_t",
        }
    }
    selinux::manage_fcontext { "/srv/wikis(/.*)?":
        type   => "httpd_sys_rw_content_t",
        before => File["/srv/wikis"],
    }

    file { [ "/srv/wikis/collab",
             "/srv/wikis/collab/archive",
             "/srv/wikis/collab/cache",
             "/srv/wikis/collab/config",
             "/srv/wikis/collab/docbook",
             "/srv/wikis/collab/htdocs",
             "/srv/wikis/collab/log",
             "/srv/wikis/collab/underlay",
             "/srv/wikis/collab/user",
             "/srv/wikis/collab/wikis",
             "/srv/wikis/collab/run", ]:
        ensure  => directory,
        mode    => "2660",
        owner   => "collab",
        group   => "collab",
        seltype => "httpd_sys_rw_content_t",
        require => [
          File["/srv/wikis"],
          User["collab"],
          Group["collab"],
          Class["wiki::moin", "wiki::collab"],
        ],
        before  => Exec["collab-create collab collab"],
    }

    exec { "collab-copy-underlay":
        user    => "root",
        path    => "/bin:/usr/bin:/sbin:/usr/sbin",
        cwd     => "${wiki::moin::shared}/underlay",
        command => "cp -R pages /srv/wikis/collab/underlay && chmod -R g=u,o-rwx /srv/wikis/collab/underlay && chown -R collab:collab /srv/wikis/collab/underlay",
        creates => "/srv/wikis/collab/underlay/pages",
        require => File["/srv/wikis/collab/underlay"],
        before  => Exec["collab-create collab collab"],
    }

    file { "/srv/wikis/collab/config/collabfarm.py":
        ensure  => present,
        mode    => "0660",
        owner   => "collab",
        group   => "collab",
        source  => [ "puppet:///private/wiki/collabfarm.py",
                     "puppet:///files/wiki/collabfarm.py",
                     "/usr/local/src/graphingwiki/collab/config/collabfarm.py", ],
        replace => false,
        seltype => "httpd_sys_rw_content_t",
        require => File["/srv/wikis/collab/config"],
        before  => Exec["collab-create collab collab"],
    }

    file { "/srv/wikis/collab/config/intermap.txt":
        ensure  => present,
        mode    => "0660",
        owner   => "collab",
        group   => "collab",
        source  => "/usr/local/src/graphingwiki/collab/config/intermap.txt",
        replace => false,
        seltype => "httpd_sys_rw_content_t",
        require => File["/srv/wikis/collab/config"],
        before  => Exec["collab-create collab collab"],
    }

    file { "/srv/wikis/collab/config/logging.conf":
        ensure  => present,
        mode    => "0660",
        owner   => "collab",
        group   => "collab",
        source  => "/usr/local/src/graphingwiki/collab/config/logging.conf",
        replace => false,
        seltype => "httpd_sys_rw_content_t",
        require => File["/srv/wikis/collab/config"],
        before  => Exec["collab-create collab collab"],
    }

    file { "/srv/wikis/collab/log/moinmoin.log":
        ensure  => present,
        mode    => "0660",
        owner   => "collab",
        group   => "collab",
        seltype => "httpd_sys_rw_content_t",
        require => File["/srv/wikis/collab/log"],
    }

    file { "/srv/wikis/collab/htdocs/.htaccess":
        ensure  => present,
        mode    => "0660",
        owner   => "collab",
        group   => "collab",
        source  => "puppet:///modules/wiki/htaccess",
        replace => false,
        seltype => "httpd_sys_rw_content_t",
        require => File["/srv/wikis/collab/htdocs"],
        before  => Exec["collab-create collab collab"],
    }

    file { [ "/etc/local", "/etc/local/collab" ]:
        ensure => directory,
        mode   => "0755",
        owner  => "root",
        group  => "root",
    }

    if $collab_jabberdomain and !$collab_conferencedomain {
        $collab_conferencedomain = "conference.${collab_jabberdomain}"
    }

    file { "/etc/local/collab/collab.ini":
        ensure  => present,
        mode    => "0644",
        owner   => "root",
        group   => "root",
        content => template("wiki/collab.ini.erb"),
        require => File["/etc/local/collab"],
        before  => Exec["collab-create collab collab"],
    }

    if !$collab_webroot {
        $collab_webroot = "/srv/www/https/*/collab"
    }

    apache::configfile { "collab.conf":
        http    => false,
        content => template("wiki/collab-httpd.conf.erb"),
    }

    exec { "collab-create collab collab":
        path    => "/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin:/usr/local/sbin",
        cwd     => "/",
        user    => "collab",
        group   => "collab",
        creates => "/srv/wikis/collab/wikis/collab",
    }
    exec { "collab-account-create -f -r collab":
        path    => "/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin:/usr/local/sbin",
        cwd     => "/",
        user    => "collab",
        group   => "collab",
        unless  => "egrep '^name=collab$' /srv/wikis/collab/user/*",
        require => Exec["collab-create collab collab"],
        before  => Cron["collab-htaccess"],
    }

    if $wiki::moin::moin_package =~ /^moin-1\.9/ {
        wiki::collab::package { "moin-English--all_pages.zip":
            source  => "/srv/wikis/collab/underlay/pages/LanguageSetup/attachments/English--all_pages.zip",
            require => Exec["collab-copy-underlay"],
        }
    }

    wiki::collab::package { "moin-CollabBase.zip":
        source  => "/usr/local/src/graphingwiki/collab/packages/CollabBase.zip",
        require => Class["wiki::collab"],
    }

    cron { "collab-htaccess":
        ensure  => present,
        command => $::operatingsystem ? {
            ubuntu  => "/usr/local/bin/collab-htaccess",
            default => "/usr/bin/collab-htaccess",
        },
        user    => "collab",
        require => [ Class["wiki::collab"], File["/srv/wikis/collab/htdocs/.htaccess"], ]
    }

    define configwebhost() {
        file { "/srv/www/https/${name}/collab":
            ensure  => link,
            target  => "/srv/wikis/collab/htdocs",
            require => File["/srv/www/https/${name}"],
        }

        file { "/srv/www/https/${name}/moin_static":
            ensure  => link,
            target  => "${wiki::moin::shared}/htdocs",
            require => File["/srv/www/https/${name}"],
        }
    }

    if $collab_webhosts {
        apache::configfile { "moin.conf":
            http   => false,
            source => "puppet:///modules/wiki/moin-httpd.conf",
        }

        configwebhost { $collab_webhosts: }
    }

}


# Use ramdisk for collab cache.
#
class wiki::collab::ramcache {

    mount { "/srv/wikis/collab/cache":
        name    => $wiki_datadir ? {
            undef   => "/srv/wikis/collab/cache",
            default => "${wiki_datadir}/collab/cache",
        },
        ensure  => mounted,
        atboot  => true,
        device  => "none",
        fstype  => "tmpfs",
        options => "uid=collab,gid=collab,mode=2770",
        dump    => "0",
        pass    => "0",
        require => File["/srv/wikis/collab/cache"],
        before  => $::operatingsystem ? {
            "ubuntu" => Service["apache2"],
            default  => Service["httpsd"],
        },
    }

}


# Install moin package.
#
# === Parameters
#
#   $name:
#       Package name.
#   $source:
#       Package file source.
#   $config:
#       Path to collab instance config dir.
#       Defaults to "/srv/wikis/collab/wikis/collab/config".
#
define wiki::collab::package($source, $config="/srv/wikis/collab/wikis/collab/config") {

    file { "/usr/local/src/${name}":
        ensure => present,
        mode   => "0644",
        owner  => "root",
        group  => "root",
        source => $source,
        notify => Exec["collab-install-${name}"],
    }

    exec { "collab-install-${name}":
        user        => "collab",
        path        => "/bin:/usr/bin:/sbin:/usr/sbin",
        environment => "PYTHONPATH=${config}",
        command     => "/bin/sh -c 'umask 007; python ${::pythonsitedir}/MoinMoin/packages.py -u collab i /usr/local/src/${name}'",
        refreshonly => true,
        require     => Exec["collab-account-create -f -r collab"]
    }

}
