<?php

use LAM\PDF\PDFTable;
use LAM\PDF\PDFTableCell;
use LAM\PDF\PDFTableRow;

/*

  This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
  Copyright (C) 2016 - 2026  Roland Gruber

  This program 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 2 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 General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

*/

/**
 * Manages memberships in NIS net groups.
 *
 * @package modules
 * @author Roland Gruber
 */

/** include parent class */
include_once(__DIR__ . "/nisNetGroupUser.inc");

/**
 * Manages memberships in NIS net groups.
 *
 * @package modules
 */
class nisNetGroupHost extends nisNetGroupUser {

	/**
	 * {@inheritDoc}
	 */
	public function can_manage(): bool {
		return $this->get_scope() === 'host';
	}

	/**
	 * {@inheritDoc}
	 */
	public function get_metaData(): array {
		$return = parent::get_metaData();
		// module dependencies
		$return['dependencies'] = ['depends' => [['account', 'posixAccount']], 'conflicts' => []];
		// upload columns
		$return['upload_columns'] = [[
			'name' => 'nisNetGroup_memberships',
			'description' => _('Memberships'),
			'help' => 'memberships_upload',
			'example' => 'group1#user#domain,group2#user#domain'
		]];
		return $return;
	}

	/**
	 * {@inheritDoc}
	 */
	protected function load_Messages(): void {
		parent::load_Messages();
		$this->messages['user'][0] = ['ERROR', _('User name'), _('User name contains invalid characters. Valid characters are: a-z, A-Z, 0-9 and .-_ !')];
	}

	/**
	 * {@inheritDoc}
	 */
	protected function isMatchingNetGroup($user, $host, $domain, $uid): bool {
		return $host == $uid;
	}

	/**
	 * Displays the group selection.
	 *
	 * @return htmlElement meta HTML code
	 */
	public function display_html_attributes() {
		$return = new htmlTable();
		$return->addElement(new htmlOutputText(_('Group')));
		$return->addElement(new htmlOutputText(_('User name')));
		$return->addElement(new htmlOutputText(_('Domain name')), true);
		for ($i = 0; $i < count($this->groups); $i++) {
			$group = $this->groups[$i];
			$return->addElement(new htmlOutputText($group['name']));
			$return->addElement(new htmlInputField('user_' . $i, $group['user']));
			$return->addElement(new htmlInputField('domain_' . $i, $group['domain']));
			$delButton = new htmlButton('del_' . $i, 'del.svg', true);
			$delButton->setTitle(_('Delete'));
			$return->addElement($delButton, true);
		}
		$return->addVerticalSpace('40px');

		// new entry
		$groupList = [];
		$groupData = $this->findGroups();
		if (count($groupData) > 0) {
			$filterGroup = new htmlGroup();
			$filterGroup->addElement(new htmlOutputText(_('Filter') . ' '));
			$filter = new htmlInputField('group_filter');
			$filter->setFieldSize(5);
			$filter->filterSelectBox('group_add');
			$filterGroup->addElement($filter);
			$return->addElement($filterGroup, true);

			foreach ($groupData as $group) {
				$groupList[$group['cn'][0]] = $group['cn'][0] . '#+#' . $group['dn'];
			}
			$groupSelect = new htmlSelect('group_add', $groupList);
			$groupSelect->setHasDescriptiveElements(true);
			$return->addElement($groupSelect);
			$return->addElement(new htmlInputField('user_add'));
			$return->addElement(new htmlInputField('domain_add'));
			$addButton = new htmlButton('addGroup', 'add.svg', true);
			$addButton->setTitle(_('Add'));
			$return->addElement($addButton, true);
		}
		return $return;
	}

	/**
	 * {@inheritDoc}
	 */
	public function process_attributes(): array {
		$errors = [];
		// add new entry
		if (isset($_POST['addGroup'])) {
			$parts = explode('#+#', $_POST['group_add']);
			$this->groups[] = [
				'name' => $parts[0],
				'dn' => $parts[1],
				'user' => $_POST['user_add'],
				'host' => $this->uidOrig,
				'domain' => $_POST['domain_add']
			];
			if (!empty($_POST['user_add']) && !get_preg($_POST['user_add'], 'username')) {
				$message = $this->messages['user'][0];
				$message[2] = $message[2] . '<br><br>' . $_POST['user_add'];
				$errors[] = $message;
			}
			if (!empty($_POST['domain_add']) && !get_preg($_POST['domain_add'], 'DNSname')) {
				$message = $this->messages['domain'][0];
				$message[2] = $message[2] . '<br><br>' . $_POST['domain_add'];
				$errors[] = $message;
			}
		}
		// check existing
		$counter = 0;
		while (isset($_POST['user_' . $counter])) {
			if (isset($_POST['del_' . $counter])) {
				unset($this->groups[$counter]);
			}
			else {
				$this->groups[$counter]['user'] = $_POST['user_' . $counter];
				if (!empty($_POST['user_' . $counter]) && !get_preg($_POST['user_' . $counter], 'username')) {
					$message = $this->messages['user'][0];
					$message[2] = $message[2] . '<br><br>' . $_POST['user_' . $counter];
					$errors[] = $message;
				}
				$this->groups[$counter]['domain'] = $_POST['domain_' . $counter];
				if (!empty($_POST['domain_' . $counter]) && !get_preg($_POST['domain_' . $counter], 'DNSname')) {
					$message = $this->messages['domain'][0];
					$message[2] = $message[2] . '<br><br>' . $_POST['domain_' . $counter];
					$errors[] = $message;
				}
			}
			$counter++;
		}
		$this->groups = array_values($this->groups);
		usort($this->groups, [$this, 'sortTriple']);
		return $errors;
	}

	/**
	 * {@inheritDoc}
	 */
	protected function createNetGroupValue(array $group, string $uid): string {
		return '(' . $uid . ',' . $group['user'] . ',' . $group['domain'] . ')';
	}

	/**
	 * {@inheritDoc}
	 */
	function get_profileOptions($typeId) {
		$groups = $this->findGroups();
		$groupOptions = ['' => ''];
		foreach ($groups as $group) {
			$groupOptions[$group['cn'][0]] = $group['cn'][0] . '#+#' . $group['dn'];
		}
		$return = new htmlResponsiveRow();
		$labels = [_('Group'), _('User name'), _('Domain name')];
		$data = [];
		for ($i = 0; $i < 5; $i++) {
			$select = new htmlSelect('nisNetGroupUser_group' . $i, $groupOptions, ['']);
			$select->setHasDescriptiveElements(true);
			$data[$i][] = $select;
			$data[$i][] = new htmlInputField('nisNetGroupUser_user' . $i);
			$data[$i][] = new htmlInputField('nisNetGroupUser_domain' . $i);
		}
		$return->add(new htmlResponsiveTable($labels, $data));
		return $return;
	}

	/**
	 * {@inheritDoc}
	 */
	public function load_profile(array $profile): void {
		for ($i = 0; $i < 5; $i++) {
			if (!empty($profile['nisNetGroupUser_group' . $i][0])) {
				$parts = explode('#+#', $profile['nisNetGroupUser_group' . $i][0]);
				$this->groups[] = [
					'name' => $parts[0],
					'dn' => $parts[1],
					'user' => $profile['nisNetGroupUser_user' . $i][0],
					'host' => $this->uidOrig,
					'domain' => $profile['nisNetGroupUser_domain' . $i][0],
				];
			}
		}
		usort($this->groups, [$this, 'sortTriple']);
	}

	/**
	 * {@inheritDoc}
	 */
	public function get_pdfEntries(array $pdfKeys, string $typeId): array {
		$return = [];
		$pdfTable = new PDFTable();
		$pdfRow = new PDFTableRow();
		$pdfRow->cells[] = new PDFTableCell(_('Group'), '25%', null, true);
		$pdfRow->cells[] = new PDFTableCell(_('User name'), '25%', null, true);
		$pdfRow->cells[] = new PDFTableCell(_('Domain name'), '25%', null, true);
		$pdfTable->rows[] = $pdfRow;
		foreach ($this->groups as $group) {
			$pdfRow = new PDFTableRow();
			$pdfRow->cells[] = new PDFTableCell($group['name'], '25%');
			$pdfRow->cells[] = new PDFTableCell($group['user'], '25%');
			$pdfRow->cells[] = new PDFTableCell($group['domain'], '25%');
			$pdfTable->rows[] = $pdfRow;
		}
		$this->addPDFTable($return, 'memberships', $pdfTable);
		return $return;
	}

	/**
	 * {@inheritDoc}
	 */
	protected function buildNetGroupTripleFromUploadValue($value, $uid): string {
		$user = empty($value[1]) ? '' : $value[1];
		$domain = empty($value[2]) ? '' : $value[2];
		return '(' . $uid . ',' . $user . ',' . $domain . ')';
	}

}