#!/usr/bin/env python3

# Copyright (C) 2023 Rudra Saraswat
# Licensed under GPL-3.0.

# Error codes
# 1 - Partitioning error
# 3 - Username not allowed

import os
import sys
import json
import yaml
import signal
import subprocess

if os.environ.get('TESTING_INST') == 'true':
    testing = True
else:
    testing = False

# State variables
mountpoints = []

########################################################################################
# Helper utils


def preexec():
    signal.signal(signal.SIGHUP, signal.SIG_IGN)
    signal.signal(signal.SIGINT, signal.SIG_IGN)
    signal.signal(signal.SIGQUIT, signal.SIG_IGN)


def exec(cmd):
    if testing:
        print(' '.join(cmd))
    else:
        subprocess.call(cmd, shell=False, stdout=sys.stdout,
                        stderr=sys.stderr, preexec_fn=preexec)


def enable_service(service):
    exec(['systemctl', 'enable', service])


def enable_user_service(service):
    exec(['systemctl', '--global', 'enable', service])


def mount(part, path):
    exec(['mount', part, path])


def mkdir(path):
    exec(['mkdir', '-p', path])

########################################################################################
# Setup base


def inst_system_config(config):
    system_config = {
        'arch-repo': 'https://geo.mirror.pkgbuild.com',
        'repo': 'https://pkg-repo.blendos.co',
        'impl': 'http://github.com/blend-os/tracks/raw/main',
        'track': 'default-gnome'
        
    }
    if 'NVIDIA' in subprocess.check_output(['lspci']).decode('utf-8'):
        system_config['packages'] = [
            'nvidia-dkms',
            'nvidia-prime',
            'switcheroo-control'
        ]

        system_config['services'] = [
            'switcheroo-control'
        ]

    if testing == False:
        with open('/system.yaml', 'w') as system_config_file:
            yaml.dump(system_config, system_config_file)
    else:
        print(system_config)


########################################################################################
# Locale


def inst_locale(config):
    # Set locale
    exec(['bash', '-c', 'echo \'en_US.UTF-8 UTF-8\' > /etc/locale.gen'])
    first_locale = True
    for locale in config['locale']['locale']:
        if locale != 'en_US.UTF-8 UTF-8':
            exec(
                ['bash', '-c', f'echo \'{locale}\' >> /etc/locale.gen'])
        if first_locale:
            exec(
                ['bash', '-c', f'echo \'LANG={locale.split()[0]}\' > /etc/locale.conf'])
            first_locale = False
    exec(['locale-gen'])

    # Set keyboard layout
    exec(
        ['bash', '-c', f'echo \'KEYMAP={config["locale"]["keymap"]}\' > /etc/vconsole.conf'])

    # Set timezone
    exec(
        ['ln', '-sf', f'/usr/share/zoneinfo/{config["locale"]["timezone"]}', '/etc/localtime'])


########################################################################################
# Networking


def inst_networking(config):
    # Set hostname
    exec(
        ['bash', '-c', f'echo \'{config["networking"]["hostname"]}\' > /etc/hostname'])

    # Create hosts file
    exec(['bash', '-c', 'echo \'127.0.0.1     localhost\' > /etc/hosts'])

    if config['networking']['ipv6']:
        # Enable ipv6
        exec(['bash', '-c', 'echo \'::1 localhost\' > /etc/hosts'])


########################################################################################
# Users


def inst_users(config):
    for home_dir in os.listdir('/home'):
        if not home_dir == 'blend':
            exec(['rm', '-rf', '/home/' + home_dir])

    # Add users
    for user in config['users']:
        exec(['useradd', '-m', '-s', '/bin/bash', user['name']])
        exec(['usermod', '-c', user['fullname'], user['name']])
        exec(
            ['bash', '-c', f'echo \'{user["name"]}:{user["password"]}\' | chpasswd'])
        exec(['usermod', '-aG', 'wheel', user['name']])
        # Add AccountsService user file
        mkdir('/mnt/var/lib/AccountsService/users')
        exec(
            ['bash', '-c', f'echo "[User]" > /var/lib/AccountsService/users/{user["name"]}'])
        exec(
            ['bash', '-c', f'echo "SystemAccount=false" >> /var/lib/AccountsService/users/{user["name"]}'])

    # Create ~/.local/share/applications with right perms
    exec(['sudo', '-u', user['name'], 'mkdir', '-p',
                f'/home/{user["name"]}/.local/share/applications'])


########################################################################################
# Akshara


def inst_akshara():
    exec(['env', 'AKSHARA_INSTALL=1', 'akshara', 'update'])


########################################################################################


signal.signal(signal.SIGHUP, signal.SIG_IGN)
signal.signal(signal.SIGINT, signal.SIG_IGN)
signal.signal(signal.SIGQUIT, signal.SIG_IGN)


try:
    if sys.argv[1] == 'config' and os.path.isfile(sys.argv[2]):
        with open(sys.argv[2]) as config_file:
            config = json.load(config_file)
            inst_system_config(config)
            inst_locale(config)
            inst_networking(config)
            inst_users(config)
            inst_akshara()

        print()
        print('===========')
        print('Successful.')

        sys.exit()
except IndexError:
    pass
