/*
 * This file is part of the KFTPGrabber project
 *
 * Copyright (C) 2003-2006 by the KFTPGrabber developers
 * Copyright (C) 2003-2006 Jernej Kos <kostko@jweb-network.net>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied
 * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and
 * NON-INFRINGEMENT.  See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Steet, Fifth Floor, Boston,
 * MA 02110-1301, USA.
 *
 * In addition, as a special exception, the copyright holders give
 * permission to link the code of portions of this program with the
 * OpenSSL library under certain conditions as described in each
 * individual source file, and distribute linked combinations
 * including the two.
 *
 * You must obey the GNU General Public License in all respects
 * for all of the code used other than OpenSSL.  If you modify
 * file(s) with this exception, you may extend this exception to your
 * version of the file(s), but you are not obligated to do so.  If you
 * do not wish to do so, delete this exception statement from your
 * version.  If you delete this exception statement from all source
 * files in the program, then also delete it here.
 */

#include "directorylisting.h"
#include "misc/filter.h"

#include <ntqdatetime.h>

#include <tdelocale.h>
#include <tdeglobal.h>
#include <kmimetype.h>

#include <sys/stat.h>

using namespace KFTPCore::Filter;
using namespace TDEIO;

namespace KFTPEngine {

DirectoryEntry::DirectoryEntry()
{
}

TDEIO::UDSEntry DirectoryEntry::toUdsEntry() const
{
  bool directory = m_type == 'd';
  UDSAtom atom;
  UDSEntry entry;
        
  atom.m_uds = UDS_NAME;
  atom.m_str = m_filename;
  entry.append(atom);
  
  atom.m_uds = UDS_SIZE;
  atom.m_long = m_size;
  entry.append(atom);
  
  atom.m_uds = UDS_MODIFICATION_TIME;
  atom.m_long = m_time;
  entry.append(atom);
  
  atom.m_uds = UDS_USER;
  atom.m_str = m_owner;
  entry.append(atom);
  
  atom.m_uds = UDS_GROUP;
  atom.m_str = m_group;
  entry.append(atom);
  
  atom.m_uds = UDS_ACCESS;
  atom.m_long = m_permissions;
  entry.append(atom);
  
  if (!m_link.isEmpty()) {
    atom.m_uds = UDS_LINK_DEST;
    atom.m_str = m_link;
    entry.append(atom);
    
    KMimeType::Ptr mime = KMimeType::findByURL(KURL("ftp://host/" + m_filename));
    if (mime->name() == KMimeType::defaultMimeType()) {
      atom.m_uds = UDS_GUESSED_MIME_TYPE;
      atom.m_str = "inode/directory";
      entry.append(atom);
      
      directory = true;
    }
  }
  
  atom.m_uds = UDS_FILE_TYPE;
  atom.m_long = directory ? S_IFDIR : S_IFREG;
  entry.append(atom);
  
  return entry;
}

TQString DirectoryEntry::timeAsString()
{
  TQDateTime dt;
  dt.setTime_t(time());

  return TDEGlobal::locale()->formatDateTime(dt);
}

bool DirectoryEntry::operator<(const DirectoryEntry &entry) const
{
  const Action *firstAction = Filters::self()->process(*this, Action::Priority);
  const Action *secondAction = Filters::self()->process(entry, Action::Priority);
  
  int priorityFirst = firstAction ? firstAction->value().toInt() : 0;
  int prioritySecond = secondAction ? secondAction->value().toInt() : 0;
  
  if (priorityFirst == prioritySecond) {
    if (isDirectory() != entry.isDirectory())
      return isDirectory();
    
    return m_filename < entry.m_filename;
  }
  
  return priorityFirst > prioritySecond;
}

DirectoryTree::DirectoryTree(DirectoryEntry entry)
  : m_entry(entry)
{
  m_directories.setAutoDelete(true);
}

void DirectoryTree::addFile(DirectoryEntry entry)
{
  m_files.append(entry);
}

DirectoryTree *DirectoryTree::addDirectory(DirectoryEntry entry)
{
  DirectoryTree *tree = new DirectoryTree(entry);
  m_directories.append(tree);
  
  return tree;
}

DirectoryListing::DirectoryListing(const KURL &path)
  : m_valid(true),
    m_path(path)
{
}

DirectoryListing::~DirectoryListing()
{
  m_list.clear();
}

void DirectoryListing::addEntry(DirectoryEntry entry)
{
  m_list.append(entry);
}

void DirectoryListing::updateEntry(const TQString &filename, ::filesize_t size)
{
  TQValueList<DirectoryEntry>::iterator listEnd = m_list.end();
  for (TQValueList<DirectoryEntry>::iterator i = m_list.begin(); i != listEnd; i++) {
    if ((*i).filename() == filename) {
      (*i).setSize(size);
      return;
    }
  }
  
  // Entry not found, add one
  DirectoryEntry entry;
  entry.setFilename(filename);
  entry.setSize(size);
  
  addEntry(entry);
}

}
