<?php

/**
 *
 * bareos-webui - Bareos Web-Frontend
 *
 * @link      https://github.com/bareos/bareos for the canonical source repository
 * @copyright Copyright (C) 2013-2024 Bareos GmbH & Co. KG (http://www.bareos.org/)
 * @license   GNU Affero General Public License (http://www.gnu.org/licenses/)
 *
 * 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/>.
 *
 */

$title = _('Restore');
$this->headTitle($title);

?>

<ul class="nav nav-tabs">
   <li class="active"><a href="<?php echo $this->url('restore', array('action' => 'index'), array('query' => $this->restore_params_generic)); ?>"><?php echo $this->translate('Restore multiple files'); ?></a></li>
   <li><a href="<?php echo $this->url('restore', array('action' => 'versions'), array('query' => $this->restore_params_generic)); ?>"><?php echo $this->translate('Restore specific file version'); ?></a></li>
</ul>

<br />

<?php if($this->acl_alert) : echo $this->ACLAlert($this->invalid_commands);
else : ?>

<!-- modal-001 start -->
<div id="modal-001" class="modal fade modal-001" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel1">
  <div class="modal-dialog modal-md">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
        <h4 class="modal-title" id="myModalLabel"><?php echo $this->translate("Failed to retrieve data from Bareos director"); ?></h4>
      </div>
      <div class="modal-body">
         <p><?php echo $this->translate("Error message received:"); ?></p>
         <p class="text-danger"><?php echo $this->errors; ?></p>
      </div>
      <div class="modal-footer">
         <button type="button" class="btn btn-primary" data-dismiss="modal"><?php echo $this->translate("Close"); ?></button>
      </div>
    </div>
  </div>
</div>
<!-- modal-001 end -->

<!-- modal-002 start (confirmation about started restore job) -->
<div id="modal-002" class="modal fade modal-002" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel2">
  <div class="modal-dialog modal-lg">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
        <h4 class="modal-title" id="myModalLabel"><?php echo $this->translate("Director message"); ?></h4>
      </div>
      <div class="modal-body">
         <pre><code>
<?php echo $this->result; ?>
         </code></pre>
      </div>
      <div class="modal-footer">
         <?php if (isset($this->restore_jobid)): ?>
            <a class="btn btn-primary" href="<?php echo $this->basePath() . '/job/details/' . $this->restore_jobid; ?>"><?php echo $this->translate("Job report"); ?></a>.
         <?php endif; ?>
         <button type="button" class="btn btn-primary" data-dismiss="modal"><?php echo $this->translate("Close"); ?></button>
      </div>
    </div>
  </div>
</div>
<!-- modal-002 end -->

<!-- modal-003 start (confirm to start restore job) -->
<div id="modal-003" class="modal fade modal-002" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel2">
  <div class="modal-dialog modal-lg">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
        <h4 class="modal-title" id="myModalLabel"><?php echo $this->translate("Confirm restore job submit"); ?></h4>
      </div>
      <div class="modal-body">
         <p>A restore job with the parameters given below will be scheduled.</p>
         <table id="restore-params-table" style="border-collapse: separate; border-spacing: 10px;">
         </table>
      </div>
      <div class="modal-footer">
         <button id="modal-003-btn-cancel" type="button" class="btn btn-default" data-dismiss="modal"><?php echo $this->translate("Cancel"); ?></button>
         <button id="modal-003-btn-ok" type="button" class="btn btn-primary"><?php echo $this->translate("OK"); ?></button>
      </div>
    </div>
  </div>
</div>
<!-- modal-003 end -->

<!-- modal-004 start -->
<div id="modal-004" class="modal fade modal-002" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel2">
  <div class="modal-dialog modal-lg">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
        <h4 class="modal-title" id="myModalLabel"></h4>
      </div>
      <div class="modal-body">
         <p><?php echo $this->translate("No files or directories selected to restore!"); ?></p>
      </div>
      <div class="modal-footer">
         <button id="modal-004-btn-ok" type="button" class="btn btn-primary" data-dismiss="modal"><?php echo $this->translate("OK"); ?></button>
      </div>
    </div>
  </div>
</div>
<!-- modal-004 end -->

<!-- modal-005 start -->
<div id="modal-005" class="modal fade modal-005" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel2">
  <div class="modal-dialog modal-md">
    <div class="modal-content">
   <div class="modal-header">
   <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
   <h4 class="modal-title" id="myModalLabel"><?php echo $this->translate("Notification"); ?></h4>
      </div>
      <div class="modal-body">
         <p><?php echo $this->translate("Restoring NDMP backups is currently not supported by Bareos WebUI. Please use the bconsole instead."); ?></p>
      </div>
      <div class="modal-footer">
         <button id="modal-005-btn-ok" type="button" class="btn btn-primary" data-dismiss="modal"><?php echo $this->translate("OK"); ?></button>
      </div>
    </div>
  </div>
</div>
<!-- modal-005 end -->

<div class="panel panel-default">
  <div class="panel-heading">
    <h3 class="panel-title">Restore</h3>
  </div>
  <div class="panel-body">
    <div class="container-fluid">

<?php
$form->prepare();
$form->setAttribute('class', 'form-horizontal');
echo $this->form()->openTag($form);
?>
      <div class="row">
        <div class="col-md-3">

<?php
echo '<p>'.$this->formRow($form->get('client')).'</p>';
echo '<p>'.$this->formRow($form->get('backups')).'</p>';
echo '<p>'.$this->formRow($form->get('mergefilesets')).'</p>';
echo '<p>'.$this->formRow($form->get('mergejobs')).'</p>';
echo '<p>'.$this->formRow($form->get('restorejob')).'</p>';
echo '<p>'.$this->formRow($form->get('restoreclient')).'</p>';
echo '<p>'.$this->formRow($form->get('replace')).'</p>';
echo '<p>'.$this->formRow($form->get('where')).'</p>';

if($restore_params['mergefilesets'] == 1) {
    foreach($form->backups as $backup) {
        if($backup['jobid'] === $this->restore_params['jobid'] && $backup['pluginjob']) {
            echo '<p>'.$this->formRow($form->get('pluginoptions')).'</p>';
        }
    }
} else {
    $pluginjobs = false;
    foreach($form->backups as $backup) {
        if($backup['pluginjob']) {
            $pluginjobs = true;
        }
    }
    if($pluginjobs) {
        echo '<p>'.$this->formRow($form->get('pluginoptions')).'</p>';
    }
}

echo '<p>'.$this->formRow($form->get('form-submit')).'</p>';

// Hidden fields
echo $this->formRow($form->get('checked_files'));
echo $this->formRow($form->get('checked_directories'));
echo $this->formRow($form->get('jobids_hidden'));
?>

        </div>

        <div class="col-md-9">

<?php
echo '<strong>';
echo $this->translate("File selection");
echo '</strong>';
?>

          <div class="panel panel-default">
            <div id="filebrowser" style="width: 100%;">
              <div style="height: 60vH;"></div>
            </div>
          </div>
        </div>
      </div>

<?php
   echo $this->form()->closeTag($form);
?>

    </div>
  </div>
</div>

<?php
echo $this->headScript()->prependFile($this->basePath() . '/js/jstreegrid-helper.js');
echo $this->headScript()->prependFile($this->basePath() . '/js/jstreegrid.js');
echo $this->headScript()->prependFile($this->basePath() . '/js/jstree.min.js');
echo $this->headLink()->prependStylesheet($this->basePath() . '/css/jstree.min.css');
?>

<style>

.jsTreeGridHeader {
   background-color: #eeeeee;
   color: #000000;
}

</style>

<script type="text/javascript">

   var modalConfirm = function(callback) {

      $("#modal-003-btn-ok").on("click", function() {
         callback(true);
         $("#modal-003").modal('hide');
      });

      $("#modal-003-btn-cancel").on("click", function() {
         callback(false);
         $("#modal-003").modal('hide');
      });

   }

   modalConfirm(function(confirm) {
      if(confirm){
         submitRestoreFormData();
      } else{
         return false;
      }
   });

   function verifyRestoreFormDataFileSelection() {

      var checked_files = [];
      var checked_directories = [];
      var checked_ids = $('#filebrowser').jstree('get_checked','full',true);

      $(checked_ids).each(function () {
         if(this.data.type === 'F') {
            checked_files.push(this.id);
         }
         else if(this.data.type === 'D') {
            checked_directories.push(Math.abs(this.id));
         }
      });

      document.getElementById('checked_files').value = checked_files.join(",");
      document.getElementById('checked_directories').value = checked_directories.join(",");

      if(checked_ids.length === 0) {
         $("#modal-004").modal();
      } else {
         let client = document.getElementById('client').value;
         let restoreclient = document.getElementById('restoreclient').value;
         let replace = document.getElementById('replace').value;
         let where = document.getElementById('where').value;
         let pluginoptions = '';
         if(document.getElementById('pluginoptions') !== null) {
            pluginoptions = document.getElementById('pluginoptions').value;
         }
         let selectedNumberOfDirectories = checked_directories.length;
         let selectedNumberOfFiles = checked_files.length;

         updateModalRestoreParamsTable(client, restoreclient, replace, where, pluginoptions, selectedNumberOfDirectories, selectedNumberOfFiles);
         $("#modal-003").modal();
      }

   }

   function submitRestoreFormData() {
      //document.getElementById('restore').submit();
      document.restore.submit();
   }

   function updateModalRestoreParamsTable(client, restoreclient, replace, where, pluginoptions, selectedNumberOfDirectories, selectedNumberOfFiles) {
      $('#restore-params-table').empty();
      $('#restore-params-table').append("<tr><td><b>Client:</b></td><td>" + client + "</td></tr>");
      $('#restore-params-table').append("<tr><td><b>Restore to client:</b></td><td>" + restoreclient + "</td></tr>");
      $('#restore-params-table').append("<tr><td><b>Replace files on client:</b></td><td>" + replace + "</td></tr>");
      $('#restore-params-table').append("<tr><td><b>Restore location on client:</b></td><td>" + where + "</td></tr>");
      $('#restore-params-table').append("<tr><td><b>Plugin Options:</b></td><td>" + pluginoptions + "</td></tr>");
      $('#restore-params-table').append("<tr><td><b>Directories selected:</b></td><td>" + selectedNumberOfDirectories + "</td></tr>");
      $('#restore-params-table').append("<tr><td><b>Files selected:</b></td><td>" + selectedNumberOfFiles + "</td></tr>");
   }

   function updateRestoreParams(k, v) {

      var p = [];
      var params = [];

      if(k === 'client') {
         p['jobid'] = '';
      } else {
         p['jobid'] = '<?php echo $this->restore_params['jobid']; ?>';
      }

      p['client'] = '<?php echo $this->restore_params['client']; ?>';

      if(k === 'client') {
         p['restoreclient'] = '';
      } else {
         p['restoreclient'] = '<?php echo $this->restore_params['restoreclient']; ?>';
      }

      p['restorejob'] = '<?php echo $this->restore_params['restorejob']; ?>';
      p['where'] = '<?php echo $this->restore_params['where']; ?>';
      p['pluginoptions'] = '<?php echo $this->restore_params['pluginoptions']; ?>';
      p['mergefilesets'] = '<?php echo $this->restore_params['mergefilesets']; ?>';
      p['mergejobs'] = '<?php echo $this->restore_params['mergejobs']; ?>';
      p['limit'] = '<?php echo $this->restore_params['limit']; ?>';

      p[k] = v;

      var key;
      for(key in p) {
         params.push(key + "=" + p[key]);
      }

      return params.join('&');
   }

   function hasValue(array) {
      for (let i = 0; i < array.length; i++) {
         let id = array[i];
         if(!document.getElementById(id).value) {
            return false;
         }
      }
      return true;
   }

   function isShowFileTreeReady()
   {
      const required_ids = ["client", "jobid"];
      return hasValue(required_ids);
   }

   function isRestoreFormReady()
   {
      if(!isShowFileTreeReady()) {
         return false;
      }
      const required_ids = ["restorejob", "restoreclient"];
      return hasValue(required_ids);
   }

   function updateSubmitButtonStatus() {
      if (isRestoreFormReady()) {
         document.getElementById('btn-form-submit').disabled = false;
      } else {
         document.getElementById('btn-form-submit').disabled = true;
      }
   }

   function displayBvfsCacheUpdateInfo() {
      $('#filebrowser').append("<br>");
      $('#filebrowser').append("<div id='alert-bvfs' class='alert alert-info' role='alert'>");
      $('#alert-bvfs').append("Update the Bvfs cache frequently to avoid timeouts.<br>");
      $('#alert-bvfs').append("Please read the Bareos Documentation for further details.");
      $('#filebrowser').append("</div>");
   }

   $(".search-input").keyup(function() {
      var searchString = $(this).val();
      $('#filebrowser').jstree('search', searchString);
   });

   $("#filebrowser").bind("loading.jstree", function() {
      displayBvfsCacheUpdateInfo();
      $('#spinner').fadeIn('slow');
   });

   $("#filebrowser").bind("ready.jstree", function() {
      $('#spinner').fadeOut('slow');
   });

   function showFileTree() {
      $('#filebrowser').jstree({
         'plugins' : [ "grid", "checkbox", "state", "sort", "search", "types" ],
         'core' : {
            'animation': false,
            'force_text': true,
            'error': function (e) {
               $('#filebrowser').html(
                  "<h4>There was an error while loading data for this tree.</h4>" +
                  "<p><b>Error: </b>" + e.error + "</p>" +
                  "<p><b>Plugin: </b>" + e.plugin + "</p>" +
                  "<p><b>Reason: </b> " + e.reason + "</p>" +
                  "<p><b>Data:</b></p>" +
                  "<pre><code>" + e.data + "</code></pre>"
               );
               displayBvfsCacheUpdateInfo();
            },
            'data' :{
               'url' : '<?php echo $this->basePath() . "/restore/filebrowser?jobid=" . $this->restore_params['jobid'] . "&client=" . $this->restore_params['client'] . "&mergefilesets=" . $this->restore_params['mergefilesets'] . "&mergejobs=" . $this->restore_params['mergejobs'] . "&limit=" . $this->restore_params['limit']; ?>',
               'dataType' : 'json',
               'data' : function (node) {
                  return { 'id' : node.id };
               },
               'timeout': <?php echo $_SESSION['bareos']['filetree_refresh_timeout']; ?>,
            },
         },
         'state' : {
            'key': 'restore'
         },
         'grid' : {
            width: '100%',
            height: '60vh',
            fixedHeader: true,
            resizable: false,
            columns: [
               {
                  width: '100%',
                  height: '100%',
                  header: '<?php echo $this->translate("Name"); ?>',
                  headerClass: 'jsTreeGridHeader',
                  title: "_DATA_"
               },
               {
                  width: 100,
                  header: '<?php echo $this->translate("Mode"); ?>',
                  headerClass: 'jsTreeGridHeader',
                  value: function(node) {
                     if(node.data === null) return null;
                     return formatJSTreeGridModeItem(node.data.stat.mode);
                  }
               },
               {
                  width: 120,
                  header: '<?php echo $this->translate("User"); ?>',
                  headerClass: 'jsTreeGridHeader',
                  value: function(node) {
                     if(node.data === null) return null;
                     return formatJSTreeGridUserItem(node);
                  }
               },
               {
                  width: 120,
                  header: '<?php echo $this->translate("Group"); ?>',
                  headerClass: 'jsTreeGridHeader',
                  value: function(node) {
                     if(node.data === null) return null;
                     return formatJSTreeGridGroupItem(node);
                  }
               },
               {
                  width: 120,
                  header: '<?php echo $this->translate("Size"); ?>',
                  headerClass: 'jsTreeGridHeader',
                  value: function(node) {
                     if(node.data === null) return null;
                     return formatJSTreeGridSizeItem(node);
                  }
               },
               {
                  width: 150,
                  header: '<?php echo $this->translate("Last modification"); ?>',
                  headerClass: 'jsTreeGridHeader',
                  value: function(node) {
                     if(node.data === null) return null;
                     return formatJSTreeGridLastModItem(node.data.stat.mtime);
                  }
               }
            ],
         },
         'search' : {
            "case_sensitive" : false,
            "show_only_matches" : false
         }
      });
   }

   $('#jobid').change(function(event) {
      window.location.href = window.location.pathname + '?' + updateRestoreParams('jobid', this.value);
   });

   $('#client').change(function(event) {
      window.location.href = window.location.pathname + '?' + updateRestoreParams('client', this.value);
   });

   $('#restoreclient').change(function(event) {
      updateSubmitButtonStatus();
   });

   $('#restorejob').change(function(event) {
      window.location.href = window.location.pathname + '?' + updateRestoreParams('restorejob', this.value);
   });

   $('#mergefilesets').change(function(event) {
      window.location.href = window.location.pathname + '?' + updateRestoreParams('mergefilesets', this.value);
   });

   $('#mergejobs').change(function(event) {
      window.location.href = window.location.pathname + '?' + updateRestoreParams('mergejobs', this.value);
   });

   $('#limit').change(function(event) {
      window.location.href = window.location.pathname + '?' + updateRestoreParams('limit', this.value);
   });

   $("#btn-form-submit").on("click", function() {
      verifyRestoreFormDataFileSelection();
   });

   $(document).ready(function(){

      var show_file_tree = true;

      var errors = '<?php echo str_replace(array("\n","\r"), "", $this->errors); ?>';
      if(errors.length > 0) {
         $("#modal-001").modal();
         show_file_tree = false;
      }

      var result = '<?php echo str_replace(array("\n","\r"), "", $this->result); ?>';
      if(result.length > 0) {
         $("#modal-002").modal();
      }

      var ndmp_advice_note = '<?php echo $this->ndmp_advice_note; ?>';
      if(ndmp_advice_note) {
         $("#modal-005").modal();
         show_file_tree = false;
      }

      if(show_file_tree && isShowFileTreeReady()) {
          showFileTree();
      }

      updateSubmitButtonStatus();

   });

</script>

<?php endif; ?>
