<?php
	
class config_admin extends Controller {
	
	public function __construct() {
		parent::__construct(dirname(__DIR__));
		hook_add('settings.filter', [$this, '__filter']);
		hook_add('modules.field.list', [$this, '__list_fields'], 1);
	}

	public function __Register() {
		$this->RegisterView(__CLASS__ .'::setup', ['setup_view' => ['render_setup']]);
		$this->RegisterView(__CLASS__ .'::system', ['setup_view' => ['render_system', 'setup_showkey']]);
		$this->RegisterView(__CLASS__ .'::keyinfo', ['setup_view' => ['render_keyinfo']]);
		$this->RegisterView(__CLASS__ .'::admin_create', ['setup_view' => ['render_select', 'render_module_settings']]);
		$this->RegisterView(__CLASS__ .'::settings', ['setup_view' => ['render_settings']]);
	}
	
	// this is only for everyone during initial setup
	/** everyone admin setup */
	public function setup() {
		// if we have admin user, then deny "everyone"
		$hasUser = hook_execute('user.levelpresent', FALSE, 10);
		$yourlevel = isset($_SESSION['current_user']) ? $_SESSION['current_user']['u_level'] : 0;
		if (!$yourlevel && $hasUser) {
			$this->HttpStatus(403);		// permission denied
			return [
				'result' => 40301,
				'message' => 'you do not have permission access to this page',
			];
		}
		
		$res = $this->DefaultResult(__METHOD__);
		$settings = $this->LoadModel('settings_model');
		$status = $settings->CheckFileSystem($this->__OUTPUT);

		if ($status->isError()) {
			$this->HttpStatus($status);
			return NULL;
		}
		$settings->SetupUserDetails($res);		// Get Single-user auth code
		
		$res['template'] = 'setup_index';
		foreach(['db_host', 'db_name', 'db_user', 'db_pass'] as $setting) {
			$res[$setting] = $this->SettingGet($setting);
			if ($setting == 'db_host' && empty($res[$setting])) $res[$setting] = 'localhost';
			if ($setting == 'db_pass') $res[$setting] = base64_decode($res[$setting]);
		}
		return $res;
	}
	
	private function _displayEntry($entry) {
		$function = $entry['function'];
		if (!empty($entry['class'])) $function = $entry['class'] . '::' . $function;
		echo $function . " [{$entry['file']}:{$entry['line']}]<br>\n";
	}
	
	/** everyone admin setup */
	public function setup_post() {
		// if we have admin user, then deny "everyone"
		$hasUser = hook_execute('user.levelpresent', FALSE, 10);
		$yourlevel = isset($_SESSION['current_user']) ? $_SESSION['current_user']['u_level'] : 0;
		if (!$yourlevel && $hasUser) {
			$this->HttpStatus(403);		// permission denied
			return [
				'result' => 40302,
				'message' => 'you do not have permission access to this page',
			];
		}
		
		$settings = $this->LoadModel('settings_model');
		if ($settings->SaveSettings($this->post())) {
			$this->redirect('/admin/system');
		} else {
			$bt = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
			foreach($bt as $bt_item) {
				echo $this->_displayEntry($bt_item);
			}
			exit;
			$this->redirect('/admin/setup?post=1');
		}
	}
    
	static $DESC_SYSTEM = 'System Settings';
	/** admin setup */
    public function system() {
		$res = $this->DefaultResult(__METHOD__);
		$settings = $this->LoadModel('settings_model');
		$res['template'] = 'setup_system';
		$active = $settings->GetPackageSettings($res, 'config');
		$res = hook_execute('settings.system', $res, $active);
		$res = hook_execute('fieldlist.filter', $res, $active);		// custom fields
		return $res;
    }

    public function system_post() {
		$settings = $this->LoadModel('settings_model');
		$res = [];
		$settings->GetPackageSettings($res, 'config');
		$res = hook_execute('settings.system', $res);
		// to do: get custom fields => add to SetPackageSettings()
		$settings->SetPackageSettings($_POST, 'config', $res);
		
		$settings = $this->SettingGet('config.module_info', NULL);
		$key = isset($settings['key']) ? $settings['key'] : '';
		if ($key != '') {
			// if admin user exists
			$hasUser = hook_execute('user.levelpresent', FALSE, 10);		// any users with the given level?
			if (!$hasUser) {
				$this->redirect('/admin/admin-create');
			}
/*				$user_info = [ 'u_level' => 10 ];	// don't care who the admin user is, only that we know one is present
				$FRAMEWORK_VAR->ExecuteHook('user.created', $user_info);		// Unlock database
				//to do: if ok, send a SettingsOk noty
				header('Location: /');
				exit;
*/			
		}
		$this->redirect('/admin/system');
	}
	
	/** admin setup */
	public function keyinfo() {
		$res = $this->DefaultResult(__METHOD__);
		$res['template'] = 'setup_keyinfo';
		return $res;
	}

	/** admin setup */
	public function showkey() {
		$settings = $this->SettingGet('config.module_info', NULL);
		$key = isset($settings['publickey']) ? $settings['publickey'] : '';
		$res = $this->DefaultResult(__METHOD__);

		$res['popup'] = [
			'title'		=> 'Public Key',
			'template'	=> 'setup_showkey',
			'modal'		=> TRUE,
			'width'		=> 700,
			'pubkey'	=> $key,
		];
		return $res;
	}
	
	public function createkey() {
		$this->model_auth = $this->LoadModel('auth_model');
		$result = $this->model_auth->CreateKey(512);
		return $result;
	}
	
	public function __filter(&$settings, $groupname) {
		if ($groupname == 'config') {
			$this->model_auth = $this->LoadModel('auth_model');
			$this->model_auth->onSaveSettings($settings);
		}
	}
	
	public function migrate() {
		$x = hook_execute('db.migrate', '', $this);
		$output = <<<BLOCK
<h3 class="templateheader">Database Migration</h3>
<pre>$x
Migration complete</pre>
BLOCK;

		return ['body' => $output];
	}

	//to do: should not have admin:
	/** setup admin */
	public function admin_create() {
		$res = $this->DefaultResult(__METHOD__);
		$settings = $this->LoadModel('settings_model');
		// get list of all available providers - email, google, facebook, wordpress, m$$, yahoo, aol
		// on post, enable the chosen module
		// advance to setup page for selected provider (along with info page with setup instructions),
		// then create new account using selected provider
		$providers = $GLOBALS['loader']->AuthenticationModules(TRUE);
		$tag = $this->param('tag', '');
		if ($tag == '') {
			$res['provider'] = $GLOBALS['loader']->GenerateProviderList($providers);
			$res['template'] = 'setup_select';
		} else {
			$info = $settings->GetProvider($providers, $tag);
			$hasSettings = $settings->EditAuthenticationSettings($res, $info, $tag);
            if ($hasSettings) {
                // Enable module, edit settings, move on to final page - 
                $res['template'] = 'setup_module';
            } else {
			//  if module does not have settings, redirect to final page
                $this->Redirect('/admin/admin-user?tag=' . rawurlencode($tag));
            }
		}
		return $res;
	}
	
	/** setup */
	public function admin_create_POST() {
		$settings = $this->LoadModel('settings_model');
		$providers = $GLOBALS['loader']->AuthenticationModules(TRUE);
		$tag = $this->param('tag', '');
		$info = $settings->GetProvider($providers, $tag);
		$settings->SaveModuleSettings($this->post(), $info);		// to do:  update settings for currently loaded module

		// level 10 user to be created:
		$auth = hook_execute('nonce.create', FALSE, 'loglevel', 10, 86400, TRUE);		// single use, expires in 24hr
		
		$param = [
					'bounce'   => '/admin/admin-created',			// to do: <-- this appears to be wrong
					'auth'     => $auth,
					'user_id'  => 0,			// not adding a login to an existing user
				];
		
		// if we have all required settings, move on to next page
		$info = hook_execute("auth.{$tag}.login", FALSE, $param);
		if ($info !== FALSE) {	
			return ['redirect' => $info['link'] ];
		} else {				// otherwise display values saved message.
			return ['result' => -9999,
					'message' => 'Changes saved - but one or more required fields are missing'];
		}
	}
    
    /** setup */
	public function admin_user() {
		$res = $this->DefaultResult(__METHOD__);
		$settings = $this->LoadModel('settings_model');
		$providers = $GLOBALS['loader']->AuthenticationModules(TRUE);
		$tag = $this->param('tag', '');
        
        $handlers = hook_execute('auth.*.login', [], ['bounce' => '/admin/admin-created']);      // bounce = page to come back to when registration confirmed
        if (!isset($handlers[$tag])) {
            header('Content-type: text/plain');
            die("\nunknown authentication handler '$tag'\n");
        }
        $info = $handlers[$tag];
        call_user_func_array($info['register'], [&$res]);
		return $res;
    }

    /** setup */
	public function admin_user_POST() {
		$res = $this->DefaultResult(__METHOD__);
		$settings = $this->LoadModel('settings_model');
		$providers = $GLOBALS['loader']->AuthenticationModules(TRUE);
		$tag = $this->param('tag', '');
        
        $handlers = hook_execute('auth.*.login', [], ['bounce' => '/admin/admin-created']);      // bounce = page to come back to when registration confirmed
        if (!isset($handlers[$tag])) {
            header('Content-type: text/plain');
            die("\nunknown authentication handler '$tag'\n");
        }
        $info = $handlers[$tag];
        call_user_func_array($info['register_post'], [&$res]);
		return $res;
    }
	
	// what fields should be listed at /admin/settings ? 
	public function __list_fields(&$result) {
		$settings = $this->LoadModel('settings_model');
		$settings->CustomFields($result);
	}
	
	// module settings
	/** admin */
	public function settings($action = '', $param1 = '', $param2 = '') { 
		$res = $this->DefaultResult(__METHOD__);
		$rep = new ReportObject;
		hook_execute('modules.field.list', $rep);
		$GLOBALS['loader']->Unscanned(TRUE);	// load inactive modules, load settings
		$settings = $this->LoadModel('settings_model');
		switch($action) {
			case 'list':
				return $settings->ModuleList($rep);
		}
		$settings->loadCustomFieldDefinitions();
		$res['template'] = 'setup_modules';
		$rep->asDataTablesDefinition($res);
		return $res;
	}

	public function settings_POST($action = '', $param1 = '', $param2 = '') { 
		$GLOBALS['loader']->Unscanned(TRUE);	// load inactive modules, load settings
		$settings = $this->LoadModel('settings_model');
		switch($action) {
			case 'edit':
				$value = array_key_exists('value', $_POST) ? trim($_POST['value']) : '';
				return $settings->ModuleEdit($param1, $param2, $value);		// save value, return empty array, or maybe a noty
		}
		return ['result' => -1900, 'message' => 'unknown action'];
	}
    
	/** setup */
	public function admin_created() {
        // user has been created. Exit maintenance mode., redirect to homepage
        $settings = $this->LoadModel('settings_model');
        $settings->ResetSingleUserMode(10);
        $this->redirect('/');
    }
    
}

/*

	
	5QIqlRtn5Juz5iz2icAFzT278RVM10X1
*/