<?php

//
// This example demonstrates how to write a drush
// script.  These scripts are run with the php-script command.
//

// drush php-script cleanflaglist.script

use Drush\Drush;

$this->output()->writeln("Flagging collection cleaning");
$this->output()->writeln("options : [delete-all | delete-nullname | delete-missing | delete-dups]");

// $this->output()->writeln("Hello world!");
$this->output()->writeln("The extra options/arguments to this command were:");
$this->output()->writeln(print_r($extra, true));

$delete_all = false;
$delete_nullname = false;
$delete_missing = false;
$recreate_missing = false;
$delete_dups = false;
$recreate_dups = false;

if (count($extra)) {
  switch ($extra[0]) {
    case "delete-all":
      $delete_all = true;
      break;
    case "delete-missing":
      $delete_missing = true;
      break;
    case "recreate-missing":
      $recreate_missing = true;
      break;
    case "delete-nullname":
      $delete_nullname = true;
      break;
    case "delete-dups":
      $delete_dups = true;
      break;
    case "recreate-dups":
      $recreate_dups = true;
      break;
  }
}


$database = \Drupal::database();

//   _   _       _ _                              
//  | \ | |_   _| | |  _ __   __ _ _ __ ___   ___ 
//  |  \| | | | | | | | '_ \ / _` | '_ ` _ \ / _ \
//  | |\  | |_| | | | | | | | (_| | | | | | |  __/
//  |_| \_|\__,_|_|_| |_| |_|\__,_|_| |_| |_|\___|
                                               
// remove flagging collection with null name
$this->output()->writeln("");
$this->output()->writeln("Flagging collection With NULL name cleaning");
$fcfd_query = $database->select('flagging_collection_field_data', 'fcfd')
  ->isNull('fcfd.name')
  ->fields('fcfd', ['id', 'relatedflag']);

$fcfd_result = $fcfd_query->execute();
$this->output()->writeln($fcfd_query->countQuery()->execute()->fetchField() . " flagging_collection with null name");

foreach ($fcfd_result as $fc) {
  // $this->output()->writeln($fc->id . " flagging_collection with null name");
  // $this->output()->writeln(print_r($fc, true));

  // get flag list items
  $flifd_query = $database->select('flag_list_item_field_data', 'flifd')
  ->condition('flifd.flag_list', $fc->id)
  ->fields('flifd', ['id', 'baseflag', 'flag_list']);

  $flifd_result = $flifd_query->execute();
  $this->output()->writeln($flifd_query->countQuery()->execute()->fetchField() . " items for fc " . $fc->id . ' with baseflag ' . $fc->relatedflag);
  // $this->output()->writeln(print_r($flifd_result->fetchAssoc(), true) . " items");

  delete_flagingcollection($fc, $database, $delete_all ? true : $delete_nullname);
}

//   __  __ _         _               ____      _       _           _   _____ _             
//  |  \/  (_)___ ___(_)_ __   __ _  |  _ \ ___| | __ _| |_ ___  __| | |  ___| | __ _  __ _ 
//  | |\/| | / __/ __| | '_ \ / _` | | |_) / _ \ |/ _` | __/ _ \/ _` | | |_  | |/ _` |/ _` |
//  | |  | | \__ \__ \ | | | | (_| | |  _ <  __/ | (_| | ||  __/ (_| | |  _| | | (_| | (_| |
//  |_|  |_|_|___/___/_|_| |_|\__, | |_| \_\___|_|\__,_|\__\___|\__,_| |_|   |_|\__,_|\__, |
//                            |___/                                                   |___/ 
// searching for missing related flags
$this->output()->writeln("");
$this->output()->writeln("Missing related flag Flagging collection cleaning");
$fcfd_query = $database->select('flagging_collection_field_data', 'fcfd')
  ->fields('fcfd', ['name', 'id', 'relatedflag']);

$fcfd_result = $fcfd_query->execute();
$this->output()->writeln($fcfd_query->countQuery()->execute()->fetchField() . " flagging_collections");

$fc_missing_relatedflag = 0;
foreach ($fcfd_result as $fc) {
  $flag_query = $database->select('config', 'c')
    ->condition('c.name', 'flag.flag.' . $fc->relatedflag)
    ->fields('c', ['name']);
  $conf_result = $flag_query->execute();
  $count = $flag_query->countQuery()->execute()->fetchField();
  if(!$count){
    $this->output()->writeln(' flagging_collection ' . $fc->name . ' ('. $fc->id . ') has ' . $count . " relatedflag");
    $fc_missing_relatedflag ++;
    delete_flagingcollection($fc, $database, $delete_all ? true : $delete_missing);
    if ($recreate_missing) {
      $FlagListsService = new FlagListsService();
      $flaggingcollection = $FlagListsService->getFlaggingCollectionById($fc->id);
      $this->output()->writeln(' flagging_collection ' . $flaggingcollection->getName());
    }
  }
}
$this->output()->writeln($fc_missing_relatedflag .' flagging_collection with missing related_flag');

//   ____              _ _           _            
//  |  _ \ _   _ _ __ | (_) ___ __ _| |_ ___  ___ 
//  | | | | | | | '_ \| | |/ __/ _` | __/ _ \/ __|
//  | |_| | |_| | |_) | | | (_| (_| | ||  __/\__ \
//  |____/ \__,_| .__/|_|_|\___\__,_|\__\___||___/
//              |_|                               
// searching for duplicates relatedflags
$this->output()->writeln("");
$this->output()->writeln("Duplicate relatedflag flagging_collection cleaning");
$dup_query = $database->select('flagging_collection_field_data', 'fcfd')
  ->fields('fcfd', ['relatedflag'])
  ->groupBy('fcfd.relatedflag')
  ->having('COUNT(*) > 1');
$dup_query->addExpression('COUNT(*)', 'count');

// $results = $query->execute()->fetchAll();

$dup_result = $dup_query->execute();
$this->output()->writeln($dup_query->countQuery()->execute()->fetchField() . " duplicate related flags");

foreach ($dup_result as $dup){
  // $this->output()->writeln($dup->relatedflag . " is dup");
  $fcfd_query = $database->select('flagging_collection_field_data', 'fcfd')
    ->condition('fcfd.relatedflag', $dup->relatedflag)
    ->fields('fcfd', ['id', 'relatedflag']);
  $fcfd_result = $fcfd_query->execute();
  $count = $fcfd_query->countQuery()->execute()->fetchField();
  
  $this->output()->writeln($dup->relatedflag . ' relatedflag has ' . $count . ' flagging collection');
  
  foreach ($fcfd_result as $fc) {
    delete_flagingcollection($fc, $database, $delete_all ? true : $delete_dups);
  }

}








// MAIN DELETE FUNCTION
function delete_flagingcollection($fc, $database, $delete){
  if($delete){
    // $this is not working in function
    // $this->output()->writeln("Deleting flagging collection " . $fc->id);
    // get flag list items
    $flifd_query = $database->select('flag_list_item_field_data', 'flifd')
    ->condition('flifd.flag_list', $fc->id)
    ->fields('flifd', ['id', 'baseflag', 'flag_list']);

    $flifd_result = $flifd_query->execute();

    foreach ($flifd_result as $item) {
      // delete items
      $database->delete('flag_list_item')
      ->condition('id', $item->id)
      ->execute();
      $database->delete('flag_list_item_field_data')
        ->condition('id', $item->id)
        ->execute();
    }

    # delete the flag_collection
    $database->delete('flagging_collection')
    ->condition('id', $fc->id)
    ->execute();
    $database->delete('flagging_collection_revision')
      ->condition('id', $fc->id)
      ->execute();
    $database->delete('flagging_collection_field_revision')
      ->condition('id', $fc->id)
      ->execute();

    # delete related flag
    // $flag_query = $database->select('config', 'c')
    //   ->condition('c.name', 'flag.flag.' . $fc->relatedflag)
    //   ->fields('c', ['name']);
    // $conf_result = $flag_query->execute();
    // $this->output()->writeln(print_r($conf_result->fetchAssoc(), true));

    $database->delete('config')
    ->condition('name', 'flag.flag.' . $fc->relatedflag)
    ->execute();

    $database->delete('config')
    ->condition('name', 'system.action.flag_action.'.$fc->relatedflag.'_flag')
    ->execute();

    $database->delete('config')
    ->condition('name', 'system.action.flag_action.'.$fc->relatedflag.'_unflag')
    ->execute();
    

    $database->delete('flagging_collection_field_data')
      ->condition('id', $fc->id)
      ->execute();

  } else {
    // $this is not working in function
    // $this->output()->writeln("In order to actually delete fault flagging collection data please use delete option");
  }

}
