<?php

/**
 * @copyright (c) Kufer Software GmbH, Loisachstrasse 4, D-84453 Mühldorf
 */

class DBWorkWBLoginsPasswords extends DBWork
{
  public function __construct($pDBTyp = 1, $pNewInstance = false)
  {
    parent::__construct($pDBTyp, $pNewInstance);
    $this->select = 'id, login, password, tnr, salt, pw_geaendert, wbloginsid';
  }

  
  public function getNewObject()
  {
    return new WBLoginPassword();
  }

  public function getTableName(): string
  {
    return 'web_wblogins_pw';
  }

  
  public function getCurrentRow($pRefreshCache = false)
  {
    $tmp = $this->getNewObject();
    $tmp->id = $this->getDatamodulValue('id');
    $tmp->login = $this->getDatamodulValue('login');
    $tmp->password = $this->getDatamodulValue('password');
    $tmp->tnr = $this->getDatamodulValue('tnr');
    $tmp->salt = $this->getDatamodulValue('salt');
    $tmp->pw_geaendert = $this->getDatamodulValue('pw_geaendert');
    $tmp->wbloginsid = $this->getDatamodulValue('wbloginsid');
    $tmp->hashversion = $this->getDatamodulValue('hashversion');

    return $tmp;
  }

  public function getByLogin($pLogin)
  {
    $login = $this->dboperation->getString4Sql($pLogin);
    $sql = 'SELECT ' . $this->select . " FROM web_wblogins_pw WHERE login = '$login'";
    $this->dboperation->clear();
    $this->dboperation->query($sql);

    return $this->getFirstRow();
  }

  public function getByTnr($pTnr)
  {
    $tnr = $this->dboperation->getInt4Sql($pTnr);
    $sql = 'SELECT ' . $this->select . " FROM web_wblogins_pw WHERE tnr = '$tnr'";
    $this->dboperation->clear();
    $this->dboperation->query($sql);

    return $this->getFirstRow();
  }

  public function existsByLogin($pLogin)
  {
    $login = $this->dboperation->getString4Sql($pLogin);
    
    $sql = "SELECT count(*) anzahl FROM web_wblogins_pw wblp inner join web_wblogins wl on wblp.wbloginsid = wl.id and wblp.tnr = wl.tnr WHERE wblp.login = '$login'";
    $this->dboperation->clear();
    $this->dboperation->query($sql);
    $this->dboperation->selectrow(0);

    return $this->getDatamodulValue('anzahl') > 0;
  }

  public function existsByTnr($pTnr)
  {
    if (!is_numeric($pTnr)) {
      return false;
    }
    
    $sql = "SELECT count(*) anzahl FROM web_wblogins_pw wblp inner join web_wblogins wl on wblp.wbloginsid = wl.id and wblp.tnr = wl.tnr WHERE wblp.tnr = $pTnr";
    $this->dboperation->clear();
    $this->dboperation->query($sql);
    $this->dboperation->selectrow(0);

    return $this->getDatamodulValue('anzahl') > 0;
  }

  
  public function isPWCorrectForLogin($pw, $pLogin)
  {
    $login = $this->dboperation->getString4Sql($pLogin);
    $sql = 'SELECT wblp.password, wblp.salt, wblp.hashversion FROM web_wblogins_pw wblp inner join web_wblogins wl on wblp.wbloginsid = wl.id and wblp.tnr = wl.tnr WHERE wblp.login=\'' . $login . '\' AND '
            . $this->datetimeop->getGueltigPart('', 'gueltig_von', 'gueltig_bis');
    $this->dboperation->clear();
    $this->dboperation->query($sql);
    $this->dboperation->selectrow(0);
    $pwfromdb = $this->getDatamodulValue('password');
    $salt = $this->getDatamodulValue('salt');
    $version = $this->getDatamodulValue('hashversion');
    $algorithmus = PasswordFactory::getByHashVersionKuferWeb($version, $salt);

    return !empty($pwfromdb) && ($algorithmus->verifyHash($pw, $pwfromdb));
  }

  
  public function isPWCorrectForTnr($pw, $tnr)
  {
    if (!is_numeric($tnr)) {
      return false;
    }
    $sql = 'SELECT wblp.password, wblp.salt, wblp.hashversion FROM web_wblogins_pw wblp inner join web_wblogins wl on wblp.wbloginsid = wl.id and wblp.tnr = wl.tnr WHERE wblp.tnr=' . $tnr . ' AND '
            . $this->datetimeop->getGueltigPart('', 'gueltig_von', 'gueltig_bis');
    $this->dboperation->clear();
    $this->dboperation->query($sql);
    $this->dboperation->selectrow(0);
    $pwfromdb = $this->getDatamodulValue('password');
    $salt = $this->getDatamodulValue('salt');
    $version = $this->getDatamodulValue('hashversion');
    $algorithmus = PasswordFactory::getByHashVersionKuferWeb($version, $salt);

    return !empty($pwfromdb) && ($algorithmus->verifyHash($pw, $pwfromdb));
  }

  
  public function insertOrUpdate($pNewPassword, $pLogin, $pTNR)
  {
    $login = null;
    if ($this->existsByLogin($pLogin)) {
      $login = $this->getByLogin($pLogin);
    } elseif ($this->existsByTnr($pTNR)) {
      $login = $this->getByTnr($pTNR);
    }
    $newLogin = $this->getNewObject();
    $newLogin->login = $pLogin;
    $newLogin->tnr = $pTNR;
    $newLogin->salt = SecurityOperations::generateSalt(); 
    $newLogin->pw_geaendert = $this->datetimeop->getFormateDateTime4ServerNow();
    $pw = \PasswordFactory::getLatestKuferWeb($newLogin->salt);
    $Hashversion = $pw->getHashversion();
    $newLogin->password = $pw->getHash($pNewPassword);
    $newLogin->hashversion = $Hashversion;
    if ($pw->getHashversion() > PasswordHashWindows1252MD5::getHashversion()) {
      $newLogin->salt = '';
    }
    $dbwWBLogin = new DBWorkWBLogins();
    $wbLogin = $dbwWBLogin->getByTnr($pTNR);
    $newLogin->wbloginsid = $wbLogin->id;
    if (is_null($login)) {
      return $this->insertWBLoginPassword($newLogin);
    } else { 
      $newLogin->id = $login->id;
      $this->updateObject($newLogin, $login, 'web_wblogins_pw', 'id', 'A', true);

      return true;
    }
  }

  
  public function changeLogin($pLoginAlt, $pLoginNeu)
  {
    $loginOld = $this->dboperation->getString4Sql($pLoginAlt);
    $loginNew = $this->dboperation->getString4Sql($pLoginNeu);
    $loginPw = null;
    if ($this->existsByLogin($loginOld)) {
      $loginPw = $this->getByLogin($loginOld);
    }

    if ($loginPw === null || $loginPw->isEmpty()) {
      return false;
    }
    $orgLogin = $loginPw->copy();


    $loginPw->login = $loginNew;

    $this->updateObject($loginPw, $orgLogin, 'web_wblogins_pw', 'id', 'A', true);

    return true;
  }

  public function deleteUnusedPassword($pLogin)
  {
    $login = $this->dboperation->getString4Sql($pLogin);
    $sql = "Delete from web_wblogins_pw where login not in (select login from web_wblogins) AND login = '$login'";
    $this->dboperation->clear();
    $this->dboperation->query($sql);
  }

  public function deleteAllUnusedPasswords()
  {
    $sql = 'Delete from web_wblogins_pw where login not in (select login from web_wblogins)';
    $this->dboperation->clear();
    $this->dboperation->query($sql);
  }

  public function getUnusedPasswordCount()
  {
    $sql = 'SELECT * from web_wblogins_pw where login not in (select login from web_wblogins)';
    $this->dboperation->clear();
    $this->dboperation->query($sql);

    return $this->dboperation->rowcount();
  }

  
  public function insertWBLoginPassword($pWBLoginPassword)
  {
    $tmp = $this->getNewObject();
    $tmp->id = $this->insertRecord('web_wblogins_pw', 'id', 'login', false);
    $pWBLoginPassword->id = $tmp->id;
    $pWBLoginPassword->pw_geaendert = $this->datetimeop->getFormateDateTime4ServerNow();
    $this->updateObject($pWBLoginPassword, $tmp, 'web_wblogins_pw', 'id', 'A', true);

    return $tmp->id;
  }

  public function getSQLValue($fieldname, $datamodul)
  {
    switch ($fieldname) {
      case 'pw_geaendert':
        return $datamodul->pw_geaendert;
      default:
        return parent::getSQLValue($fieldname, $datamodul);
    }
  }
}