# Copyright 2016 Canonical, Ltd.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import logging
import os
import time

from subiquitycore import utils


log = logging.getLogger("subiquitycore.user")


def create_user(userinfo, dryrun=False):
    """Create a user according to the information in userinfo."""
    usercmds = []
    # FIXME: snappy needs --extrausers too; should factor out a way to pass
    #        additional parameters.
    usercmds += ["useradd -m -p {confirm_password} {username}".format(**userinfo)]
    if 'ssh_import_id' in userinfo:
        target = "/home/{username}/.ssh/authorized_keys".format(**userinfo)
        userinfo.update({'target': target})
        ssh_id = userinfo.get('ssh_import_id')
        if ssh_id.startswith('sso'):
            log.info('call out to SSO login')
        else:
            ssh_import_id = "ssh-import-id -o "
            ssh_import_id += "{target} {ssh_import_id}".format(**userinfo)
            usercmds += [ssh_import_id]

    if not dryrun:
        # TODO(mwhudson): cmd.split? really? what if the password contains a space?
        for cmd in usercmds:
            utils.run_command(cmd.split(), shell=False)

        # always run chown last
        homedir = '/home/{username}'.format(**userinfo)
        retries = 10
        while not os.path.exists(homedir) and retries > 0:
            log.debug('waiting on homedir')
            retries -= 1
            time.sleep(0.2)

        if retries <= 0:
            raise ValueError('Failed to create homedir')

        chown = "chown {username}.{username} -R /home/{username}".format(**userinfo)
        utils.run_command(chown.split(), shell=False)

        # add sudo rule
        with open('/etc/sudoers.d/firstboot-user', 'w') as fh:
            fh.write('# firstboot config added user\n\n')
            fh.write('{username} ALL=(ALL) NOPASSWD:ALL\n'.format(**userinfo))
    else:
        log.info('dry-run, skiping user configuration')

@@ -744,16 +744,22 @@
 core
+.utils
  import 
 util
@@ -754,21 +754,27 @@
  import 
-utils
+run_command
 %0A%0A%0Alog =
@@ -941,16 +941,53 @@
 ds = %5B%5D%0A
+    username = userinfo%5B'username'%5D%0A%0A
     # FI
@@ -1098,22 +1098,20 @@
     user
-cmds +
+add 
 = %5B%22user
@@ -1117,16 +1117,33 @@
 radd
- -m -p %7B
+%22, %22-m%22, %22-p%22, userinfo%5B'
 conf
@@ -1158,19 +1158,20 @@
 word
-%7D %7B
+'%5D, 
 username
 %7D%22.f
@@ -1170,30 +1170,38 @@
 name
-%7D%22.format(**userinfo)%5D
+%5D%0A    usercmds.append(useradd)
 %0A   
@@ -1258,24 +1258,16 @@
 %22/home/%7B
-username
 %7D/.ssh/a
@@ -1293,62 +1293,16 @@
 mat(
-**
 user
-info)%0A        userinfo.update(%7B'target': target%7D
+name
 )%0A  
@@ -1328,13 +1328,9 @@
 info
-.get(
+%5B
 'ssh
@@ -1340,17 +1340,17 @@
 port_id'
-)
+%5D
 %0A       
@@ -1467,16 +1467,17 @@
 rt_id = 
+%5B
 %22ssh-imp
@@ -1486,88 +1486,32 @@
 t-id
- -o %22%0A            ssh_import_id += %22%7B
+%22, %22-o%22, 
 target
-%7D %7B
+, 
 ssh_i
-mport_id%7D%22.format(**userinfo)
+d%5D
 %0A   
@@ -1531,13 +1531,16 @@
 cmds
- += %5B
+.append(
 ssh_
@@ -1548,17 +1548,17 @@
 mport_id
-%5D
+)
 %0A%0A    if
@@ -1582,112 +1582,78 @@
     
-# TODO(mwhudson): cmd.split? really? what if the password contains a space?%0A        for cmd in usercmds:
+for cmd in usercmds:%0A            # TODO(mwhudson): Check return value!
 %0A   
@@ -1653,38 +1653,32 @@
 ue!%0A            
-utils.
 run_command(cmd.
@@ -1676,24 +1676,16 @@
 mand(cmd
-.split()
 , shell=
@@ -1749,25 +1749,28 @@
  '/home/
-%7B
+' + 
 username
 %7D'.forma
@@ -1765,29 +1765,8 @@
 name
-%7D'.format(**userinfo)
 %0A   
@@ -2043,76 +2043,106 @@
 n = 
+%5B
 %22chown
- %7Busername%7D.%7Busername%7D -R /home/%7Busername%7D%22.format(**userinfo)
+%22, %22%7B0%7D.%7B0%7D%22.format(username), %22-R%22, homedir%5D%0A        # TODO(mwhudson): Check return value!
 %0A   
@@ -2150,14 +2150,8 @@
     
-utils.
 run_
@@ -2167,16 +2167,8 @@
 hown
-.split()
 , sh
@@ -2347,24 +2347,16 @@
 write('%7B
-username
 %7D ALL=(A
@@ -2386,18 +2386,16 @@
 mat(
-**
 user
-info
+name
 ))%0A 

Make create_user resilient to e.g. spaces in the password.