#!/usr/local/bin/python2.7
# -*- coding: utf-8 -*-

# (c) 2012, Boyd Adamson <boyd () boydadamson.com>
#
# This file is part of Ansible
#
# Ansible 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 3 of the License, or
# (at your option) any later version.
#
# Ansible 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 Ansible.  If not, see <http://www.gnu.org/licenses/>.
#

DOCUMENTATION = '''
---
module: svr4pkg
short_description: Manage Solaris SVR4 packages
description:
    - Manages SVR4 packages on Solaris 10 and 11.
    - These were the native packages on Solaris <= 10 and are available
      as a legacy feature in Solaris 11.
    - Note that this is a very basic packaging system. It will not enforce
      dependencies on install or remove.
version_added: 0.9
author: Boyd Adamson
options:
  name:
    description:
      - Package name, e.g. C(SUNWcsr)
    required: true

  state:
    description:
      - Whether to install (C(present)), or remove (C(absent)) a package.
      - If the package is to be installed, then I(src) is required.
      - The SVR4 package system doesn't provide an upgrade operation. You need to uninstall the old, then install the new package.
    required: true
    choices: ["present", "absent"]

  src:
    description:
      - Specifies the location to install the package from. Required when C(state=present).
      - "Can be any path acceptable to the C(pkgadd) command's C(-d) option. e.g.: C(somefile.pkg), C(/dir/with/pkgs), C(http:/server/mypkgs.pkg)."
      - If using a file or directory, they must already be accessible by the host. See the M(copy) module for a way to get them there.
  proxy:
    description:
      - HTTP[s] proxy to be used if C(src) is a URL.

examples:
  - code: svr4pkg name=CSWcommon src=/tmp/cswpkgs.pkg state=present
    description: Install a package from an already copied file
  - code: 'svr4pkg name=CSWpkgutil src=http://get.opencsw.org/now state=present'
    description: Install a package directly from an http site
  - code: svr4pkg name=SUNWgnome-sound-recorder state=absent
    description: Ensure that a package is not installed.
'''
import os
import tempfile

def package_installed(module, name):
    cmd = [module.get_bin_path('pkginfo', True)]
    cmd.append('-q')
    cmd.append(name)
    res = subprocess.call(cmd)
    if res == 0:
        return True
    else:
        return False

def create_admin_file():
    (desc, filename) = tempfile.mkstemp(prefix='ansible_svr4pkg', text=True)
    fullauto = '''
mail=
instance=unique
partial=nocheck
runlevel=quit
idepend=nocheck
rdepend=nocheck
space=quit
setuid=nocheck
conflict=nocheck
action=nocheck
networktimeout=60
networkretries=3
authentication=quit
keystore=/var/sadm/security
proxy=
basedir=default
'''
    os.write(desc, fullauto)
    os.close(desc)
    return filename

def run_command(module, cmd):
    progname = cmd[0]
    cmd[0] = module.get_bin_path(progname, True)
    p = subprocess.Popen(cmd, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    (out, err) = p.communicate()
    rc = p.returncode
    return (rc, out, err)

def package_install(module, name, src, proxy):
    adminfile = create_admin_file()
    cmd = [ 'pkgadd', '-na', adminfile, '-d', src ]
    if proxy is not None:
        cmd += [ '-x', proxy ]
    cmd.append(name)
    (rc, out, err) = run_command(module, cmd)
    os.unlink(adminfile)
    return (rc, out, err)

def package_uninstall(module, name, src):
    adminfile = create_admin_file()
    cmd = [ 'pkgrm', '-na', adminfile, name]
    (rc, out, err) = run_command(module, cmd)
    os.unlink(adminfile)
    return (rc, out, err)

def main():
    module = AnsibleModule(
        argument_spec = dict(
            name = dict(required = True),
            state = dict(required = True, choices=['present', 'absent']),
            src = dict(default = None),
            proxy = dict(default = None)
            )
        )
    state = module.params['state']
    name = module.params['name']
    src = module.params['src']
    proxy = module.params['proxy']
    rc = None
    out = ''
    err = ''
    result = {}
    result['name'] = name
    result['state'] = state

    if state == 'present':
        if src is None:
            module.fail_json(name=name,
                             msg="src is required when state=present")
        if not package_installed(module, name):
            (rc, out, err) = package_install(module, name, src, proxy)
            # Stdout is normally empty but for some packages can be
            # very long and is not often useful
            if len(out) > 75:
                out = out[:75] + '...'

    elif state == 'absent':
        if package_installed(module, name):
            (rc, out, err) = package_uninstall(module, name, src)
            out = out[:75]

    if rc is None:
        result['changed'] = False
    else:
        result['changed'] = True

    if out:
        result['stdout'] = out
    if err:
        result['stderr'] = err

    module.exit_json(**result)

# include magic from lib/ansible/module_common.py
#<<INCLUDE_ANSIBLE_MODULE_COMMON>>
main()
