/* -*- Mode: Vala; indent-tabs-mode: nil; tab-width: 2 -*-
 *
 * SPDX-License-Identifier: GPL-3.0-or-later
 * SPDX-FileCopyrightText: Michael Terry
 */

using GLib;

[GtkTemplate (ui = "/org/gnome/DejaDup/ConfigFolderRow.ui")]
public class ConfigFolderRow : Adw.ActionRow
{
  public File file {get; set;}
  public bool check_access {get; set;}
  public bool check_size {get; set;}

  public signal void remove_clicked();

  [GtkChild]
  unowned HelpButton warning_button;
  [GtkChild]
  unowned Gtk.Label warning_label;

  Cancellable cancel_scan;

  construct {
    cancel_scan = new Cancellable();

    start_scan_size();

    notify["file"].connect(() => {update_row.begin();});
    notify["check-access"].connect(() => {update_row.begin();});
    update_row.begin();
  }

  [GtkCallback]
  void start_scan_size()
  {
    scan_size.begin();
  }

  async void scan_size()
  {
    // reset state
    subtitle = "";
    cancel_scan.cancel();
    cancel_scan.reset();

    if (file == null || !check_size)
      return;

    subtitle = C_("scanning a folder for its disk usage", "Scanning…");

    try {
      uint64 disk;
      yield file.measure_disk_usage_async(
        // We measure apparent size because neither Duplicity nor Restic optimize sparse files when
        // backing up. So let's use the size they'll report to the user (and take up in repo).
        FileMeasureFlags.APPARENT_SIZE, Priority.LOW, cancel_scan, null, out disk, null, null
      );
      subtitle = format_size(disk);
    } catch (IOError.NOT_FOUND e) {
      // update_row() will show warning to user for us
      subtitle = format_size(0);
    } catch (IOError.CANCELLED e) {
      return;
    } catch (Error e) {
      subtitle = e.message;
    }
  }

  async void update_row()
  {
    title = file == null ? "" : yield DejaDup.get_nickname(file);

    var has_warning = false;
    if (check_access && file != null) {
      var install_env = DejaDup.InstallEnv.instance();

      // Keep this list of rules in sync with OperationBackup's
      // filter on include/excludes.
      if (!file.is_native()) {
        warning_label.label = _("This folder cannot be backed up because it is a network folder.");
        has_warning = true;
      } else if (!install_env.is_file_available(file)) {
        warning_label.label = _("This folder cannot be backed up because Backups does not have access to it.");
        has_warning = true;
      }
    }

    if (file != null && !has_warning && !file.query_exists()) {
      warning_label.label = _("This folder does not exist.");
      has_warning = true;
    }

    if (has_warning) {
      warning_button.visible = true;
      add_css_class("warning");
    } else {
      warning_button.visible = false;
      remove_css_class("warning");
    }
  }

  [GtkCallback]
  void on_remove_clicked()
  {
    remove_clicked();
  }
}
