/**
 * Fills mailbox object
 *
 * this is passed the mailbox array by left_main.php
 * who has previously obtained it from sqimap_get_mailboxes
 * that way, the raw mailbox list is available in left_main to other
 * things besides just sqimap_mailbox_tree
 * imap_stream is just used now to get status info
 *
 * most of the functionality is moved to sqimap_get_mailboxes
 * also takes care of TODO items:
 * caching mailbox tree
 * config setting for UW imap section (not needed now)
 *
 * Some code fragments are present in 1.3.0 - 1.4.4.
 * @param stream $imap_stream imap connection resource
 * @param array $lsub_ary output array from sqimap_get_mailboxes (contains mailboxes and flags)
 * @return object see mailboxes class.
 * @since 1.5.0
 */
function sqimap_mailbox_tree($imap_stream, $lsub_ary)
{
    $sorted_lsub_ary = array();
    $cnt = count($lsub_ary);
    for ($i = 0; $i < $cnt; $i++) {
        $mbx = $lsub_ary[$i]['unformatted'];
        $flags = $lsub_ary[$i]['flags'];
        $noinferiors = 0;
        if (in_array('\\Noinferiors', $flags)) {
            $noinferiors = 1;
        }
        if (in_array('\\NoInferiors', $flags)) {
            $noinferiors = 1;
        }
        if (in_array('\\HasNoChildren', $flags)) {
            $noinferiors = 1;
        }
        $noselect = 0;
        if (in_array('\\NoSelect', $flags)) {
            $noselect = 1;
        }
        /**
         * LIST (SUBSCRIBED) has two new flags, \NonExistent which means the mailbox is subscribed to
         * but doesn't exist, and \PlaceHolder which is similar (but not the same) as \NoSelect
         * For right now, we'll treat these the same as \NoSelect and this behavior can be changed
         * later if needed
         */
        if (in_array('\\NonExistent', $flags)) {
            $noselect = 1;
        }
        if (in_array('\\PlaceHolder', $flags)) {
            $noselect = 1;
        }
        $sorted_lsub_ary[] = array('mbx' => $mbx, 'noselect' => $noselect, 'noinferiors' => $noinferiors);
    }
    $sorted_lsub_ary = array_values($sorted_lsub_ary);
    usort($sorted_lsub_ary, 'mbxSort');
    $boxestree = sqimap_fill_mailbox_tree($sorted_lsub_ary, false, $imap_stream);
    return $boxestree;
}
function sqimap_mailbox_tree($imap_stream)
{
    global $boxesnew, $default_folder_prefix, $unseen_notify, $unseen_type;
    if (!isset($boxesnew)) {
        global $data_dir, $username, $list_special_folders_first, $folder_prefix, $delimiter, $trash_folder, $move_to_trash;
        $inbox_in_list = false;
        $inbox_subscribed = false;
        require_once SM_PATH . 'include/load_prefs.php';
        /* LSUB array */
        $lsub_ary = sqimap_run_command($imap_stream, "LSUB \"{$folder_prefix}\" \"*\"", true, $response, $message);
        /*
         * Section about removing the last element was removed 
         * We don't return "* OK" anymore from sqimap_read_data
         */
        $sorted_lsub_ary = array();
        $cnt = count($lsub_ary);
        for ($i = 0; $i < $cnt; $i++) {
            /*
             * Workaround for EIMS
             * Doesn't work if the mailbox name is multiple lines
             */
            if (isset($lsub_ary[$i + 1]) && ereg("^(\\* [A-Z]+.*)\\{[0-9]+\\}([ \n\r\t]*)\$", $lsub_ary[$i], $regs)) {
                $i++;
                $lsub_ary[$i] = $regs[1] . '"' . addslashes(trim($lsub_ary[$i])) . '"' . $regs[2];
            }
            /*
            if (preg_match("/^\*\s+LSUB\s+\((.*)\)\s+\"(.*)\"\s+\"?(.+(?=\")|.+).*$/",$lsub_ary[$i],$regs)) {
                $flag = $regs[1];
                $mbx = trim($regs[3]);
                $sorted_lsub_ary[] = array ('mbx' => $mbx, 'flag' => $flag); 
            }
            */
            $mbx = find_mailbox_name($lsub_ary[$i]);
            $noselect = check_is_noselect($lsub_ary[$i]);
            if (substr($mbx, -1) == $delimiter) {
                $mbx = substr($mbx, 0, strlen($mbx) - 1);
            }
            $sorted_lsub_ary[] = array('mbx' => $mbx, 'noselect' => $noselect);
        }
        array_multisort($sorted_lsub_ary, SORT_ASC, SORT_REGULAR);
        for ($i = 0; $i < $cnt; $i++) {
            if ($sorted_lsub_ary[$i]['mbx'] == 'INBOX') {
                $inbox_in_list = true;
                break;
            }
        }
        /*
         * Just in case they're not subscribed to their inbox,
         * we'll get it for them anyway
         */
        if (!$inbox_in_list) {
            $inbox_ary = sqimap_run_command($imap_stream, "LIST \"\" \"INBOX\"", true, $response, $message);
            /* Another workaround for EIMS */
            if (isset($inbox_ary[1]) && ereg("^(\\* [A-Z]+.*)\\{[0-9]+\\}([ \n\r\t]*)\$", $inbox_ary[0], $regs)) {
                $inbox_ary[0] = $regs[1] . '"' . addslashes(trim($inbox_ary[1])) . '"' . $regs[2];
            }
            $mbx = find_mailbox_name($inbox_ary[0]);
            if (substr($mbx, -1) == $delimiter) {
                $mbx = substr($mbx, 0, strlen($mbx) - 1);
            }
            if ($mbx == 'INBOX') {
                $sorted_lsub_ary[] = array('mbx' => $mbx, 'flag' => '');
                sqimap_subscribe($imap_stream, 'INBOX');
                $cnt++;
            }
            /*
            if (preg_match("/^\*\s+LIST\s+\((.*)\)\s+\"(.*)\"\s+\"?(.+(?=\")|.+).*$/",$inbox_ary[0],$regs)) {
                $flag = $regs[1];
                $mbx = trim($regs[3]);
                if (substr($mbx, -1) == $delimiter) {
                    $mbx = substr($mbx, 0, strlen($mbx) - 1);
                }
                $sorted_lsub_ary[] = array ('mbx' => $mbx, 'flag' => $flag); 
            }
            */
        }
        for ($i = 0; $i < $cnt; $i++) {
            $mbx = $sorted_lsub_ary[$i]['mbx'];
            if ($unseen_notify == 2 && $mbx == 'INBOX' || $unseen_notify == 3 || $move_to_trash && $mbx == $trash_folder) {
                if ($sorted_lsub_ary[$i]['noselect']) {
                    $sorted_lsub_ary[$i]['unseen'] = 0;
                } else {
                    $sorted_lsub_ary[$i]['unseen'] = sqimap_unseen_messages($imap_stream, $mbx);
                }
                if ($unseen_type == 2 || $move_to_trash && $mbx == $trash_folder || $mbx == $trash_folder) {
                    if ($sorted_lsub_ary[$i]['noselect']) {
                        $sorted_lsub_ary[$i]['nummessages'] = 0;
                    } else {
                        $sorted_lsub_ary[$i]['nummessages'] = sqimap_get_num_messages($imap_stream, $mbx);
                    }
                }
            }
        }
        $boxesnew = sqimap_fill_mailbox_tree($sorted_lsub_ary);
        return $boxesnew;
    }
}
function sqimap_mailbox_tree($imap_stream)
{
    global $default_folder_prefix, $unseen_notify, $unseen_type;
    if (true) {
        global $data_dir, $username, $list_special_folders_first, $folder_prefix, $delimiter, $trash_folder, $move_to_trash, $imap_server_type;
        $inbox_in_list = false;
        $inbox_subscribed = false;
        $noselect = false;
        $noinferiors = false;
        require_once SM_PATH . 'include/load_prefs.php';
        /* LSUB array */
        $lsub_ary = sqimap_run_command($imap_stream, "LSUB \"{$folder_prefix}\" \"*\"", true, $response, $message);
        $lsub_ary = compact_mailboxes_response($lsub_ary);
        /* Check to see if we have an INBOX */
        $has_inbox = false;
        for ($i = 0, $cnt = count($lsub_ary); $i < $cnt; $i++) {
            if (preg_match("/^\\*\\s+LSUB.*\\s\"?INBOX\"?[^(\\/\\.)].*\$/i", $lsub_ary[$i])) {
                $lsub_ary[$i] = strtoupper($lsub_ary[$i]);
                // in case of an unsubscribed inbox an imap server can
                // return the inbox in the lsub results with a \NoSelect
                // flag.
                if (!preg_match("/\\*\\s+LSUB\\s+\\(.*\\\\NoSelect.*\\).*/i", $lsub_ary[$i])) {
                    $has_inbox = true;
                } else {
                    // remove the result and request it again  with a list
                    // response at a later stage.
                    unset($lsub_ary[$i]);
                    // re-index the array otherwise the addition of the LIST
                    // response will fail in PHP 4.1.2 and probably other older versions
                    $lsub_ary = array_values($lsub_ary);
                }
                break;
            }
        }
        if ($has_inbox == false) {
            // do a list request for inbox because we should always show
            // inbox even if the user isn't subscribed to it.
            $inbox_ary = sqimap_run_command($imap_stream, 'LIST "" INBOX', true, $response, $message);
            $inbox_ary = compact_mailboxes_response($inbox_ary);
            if (count($inbox_ary)) {
                $lsub_ary[] = $inbox_ary[0];
            }
        }
        /*
         * Section about removing the last element was removed
         * We don't return "* OK" anymore from sqimap_read_data
         */
        $sorted_lsub_ary = array();
        $cnt = count($lsub_ary);
        for ($i = 0; $i < $cnt; $i++) {
            $mbx = find_mailbox_name($lsub_ary[$i]);
            // only do the noselect test if !uw, is checked later. FIX ME see conf.pl setting
            if ($imap_server_type != "uw") {
                $noselect = check_is_noselect($lsub_ary[$i]);
                $noinferiors = check_is_noinferiors($lsub_ary[$i]);
            }
            if (substr($mbx, -1) == $delimiter) {
                $mbx = substr($mbx, 0, strlen($mbx) - 1);
            }
            $sorted_lsub_ary[] = array('mbx' => $mbx, 'noselect' => $noselect, 'noinferiors' => $noinferiors);
        }
        // FIX ME this requires a config setting inside conf.pl instead of checking on server type
        if ($imap_server_type == "uw") {
            $aQuery = array();
            $aTag = array();
            // prepare an array with queries
            foreach ($sorted_lsub_ary as $aMbx) {
                $mbx = stripslashes($aMbx['mbx']);
                sqimap_prepare_pipelined_query('LIST "" ' . sqimap_encode_mailbox_name($mbx), $tag, $aQuery, false);
                $aTag[$tag] = $mbx;
            }
            $sorted_lsub_ary = array();
            // execute all the queries at once
            $aResponse = sqimap_run_pipelined_command($imap_stream, $aQuery, false, $aServerResponse, $aServerMessage);
            foreach ($aTag as $tag => $mbx) {
                if ($aServerResponse[$tag] == 'OK') {
                    $sResponse = implode('', $aResponse[$tag]);
                    $noselect = check_is_noselect($sResponse);
                    $noinferiors = check_is_noinferiors($sResponse);
                    $sorted_lsub_ary[] = array('mbx' => $mbx, 'noselect' => $noselect, 'noinferiors' => $noinferiors);
                }
            }
            $cnt = count($sorted_lsub_ary);
        }
        $sorted_lsub_ary = array_values($sorted_lsub_ary);
        usort($sorted_lsub_ary, 'mbxSort');
        $boxestree = sqimap_fill_mailbox_tree($sorted_lsub_ary, false, $imap_stream);
        return $boxestree;
    }
}