/* GIO - GLib Input, Output and Streaming Library
 *
 * Copyright (C) 2014 Patrick Griffis
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General
 * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
 *
 */

#include "config.h"

#include "gcontenttype.h"
#include "gicon.h"
#include "gthemedicon.h"

#include <CoreServices/CoreServices.h>


/*< internal >
 * create_cfstring_from_cstr:
 * @cstr: a #gchar
 *
 * Converts a cstr to a utf8 cfstring
 * It must be CFReleased()'d.
 *
 */
static CFStringRef
create_cfstring_from_cstr (const gchar *cstr)
{
  return CFStringCreateWithCString (NULL, cstr, kCFStringEncodingUTF8);
}

/*< internal >
 * create_cstr_from_cfstring:
 * @str: a #CFStringRef
 *
 * Converts a cfstring to a utf8 cstring.
 * The incoming cfstring is released for you.
 * The returned string must be g_free()'d.
 *
 */
static gchar *
create_cstr_from_cfstring (CFStringRef str)
{
  const gchar *cstr;

  if (str == NULL)
    return NULL;

  cstr = CFStringGetCStringPtr (str, kCFStringEncodingUTF8);
  CFRelease (str);

  return g_strdup (cstr);
}

/*< internal >
 * create_cstr_from_cfstring_with_fallback:
 * @str: a #CFStringRef
 * @fallback: a #gchar
 *
 * Tries to convert a cfstring to a utf8 cstring.
 * If @str is NULL or conversion fails @fallback is returned.
 * The incoming cfstring is released for you.
 * The returned string must be g_free()'d.
 *
 */
static gchar *
create_cstr_from_cfstring_with_fallback (CFStringRef  str,
                                         const gchar *fallback)
{
  gchar *cstr;

  cstr = create_cstr_from_cfstring (str);
  if (!cstr)
    return g_strdup (fallback);

  return cstr;
}

gboolean
g_content_type_equals (const gchar *type1,
                       const gchar *type2)
{
  CFStringRef str1, str2;
  gboolean ret;

  g_return_val_if_fail (type1 != NULL, FALSE);
  g_return_val_if_fail (type2 != NULL, FALSE);

  if (g_ascii_strcasecmp (type1, type2) == 0)
    return TRUE;

  str1 = create_cfstring_from_cstr (type1);
  str2 = create_cfstring_from_cstr (type2);

  ret = UTTypeEqual (str1, str2);

  CFRelease (str1);
  CFRelease (str2);

  return ret;
}

gboolean
g_content_type_is_a (const gchar *ctype,
                     const gchar *csupertype)
{
  CFStringRef type, supertype;
  gboolean ret;

  g_return_val_if_fail (ctype != NULL, FALSE);
  g_return_val_if_fail (csupertype != NULL, FALSE);

  type = create_cfstring_from_cstr (ctype);
  supertype = create_cfstring_from_cstr (csupertype);

  ret = UTTypeConformsTo (type, supertype);

  CFRelease (type);
  CFRelease (supertype);

  return ret;
}

gboolean
g_content_type_is_unknown (const gchar *type)
{
  g_return_val_if_fail (type != NULL, FALSE);

  /* Should dynamic types be considered "unknown"? */
  if (g_str_has_prefix (type, "dyn."))
    return TRUE;
  /* application/octet-stream */
  else if (g_strcmp0 (type, "public.data") == 0)
    return TRUE;

  return FALSE;
}

gchar *
g_content_type_get_description (const gchar *type)
{
  CFStringRef str;
  CFStringRef desc_str;

  g_return_val_if_fail (type != NULL, NULL);

  str = create_cfstring_from_cstr (type);
  desc_str = UTTypeCopyDescription (str);

  CFRelease (str);
  return create_cstr_from_cfstring_with_fallback (desc_str, "unknown");
}

static GIcon *
g_content_type_get_icon_internal (const gchar *type,
                                  gboolean     symbolic)
{
  GIcon *icon = NULL;
  gchar *name;

  g_return_val_if_fail (type != NULL, NULL);

  /* TODO: Show mimetype icons. */
  if (g_content_type_can_be_executable (type))
    name = "gtk-execute";
  else if (g_content_type_is_a (type, "public.directory"))
    name = symbolic ? "inode-directory-symbolic" : "inode-directory";
  else
    name = "gtk-file";

  icon = g_themed_icon_new_with_default_fallbacks (name);

  return icon;
}

GIcon *
g_content_type_get_icon (const gchar *type)
{
  return g_content_type_get_icon_internal (type, FALSE);
}

GIcon *
g_content_type_get_symbolic_icon (const gchar *type)
{
  return g_content_type_get_icon_internal (type, TRUE);
}

gchar *
g_content_type_get_generic_icon_name (const gchar *type)
{
  return NULL;
}

gboolean
g_content_type_can_be_executable (const gchar *type)
{
  CFStringRef uti;
  gboolean ret = FALSE;

  g_return_val_if_fail (type != NULL, FALSE);

  uti = create_cfstring_from_cstr (type);

  if (UTTypeConformsTo (uti, kUTTypeApplication))
    ret = TRUE;
  else if (UTTypeConformsTo (uti, CFSTR("public.executable")))
    ret = TRUE;
  else if (UTTypeConformsTo (uti, CFSTR("public.script")))
    ret = TRUE;

  CFRelease (uti);
  return ret;
}

gchar *
g_content_type_from_mime_type (const gchar *mime_type)
{
  CFStringRef mime_str;
  CFStringRef uti_str;

  g_return_val_if_fail (mime_type != NULL, NULL);

  /* Their api does not handle globs but they are common. */
  if (g_str_has_suffix (mime_type, "*"))
    {
      if (g_str_has_prefix (mime_type, "audio"))
        return g_strdup ("public.audio");
      if (g_str_has_prefix (mime_type, "image"))
        return g_strdup ("public.image");
      if (g_str_has_prefix (mime_type, "text"))
        return g_strdup ("public.text");
      if (g_str_has_prefix (mime_type, "video"))
        return g_strdup ("public.movie");
    }

  /* Some exceptions are needed for gdk-pixbuf.
   * This list is not exhaustive.
   */
  if (g_str_has_prefix (mime_type, "image"))
    {
      if (g_str_has_suffix (mime_type, "x-icns"))
        return g_strdup ("com.apple.icns");
      if (g_str_has_suffix (mime_type, "x-tga"))
        return g_strdup ("com.truevision.tga-image");
      if (g_str_has_suffix (mime_type, "x-ico"))
        return g_strdup ("com.microsoft.ico ");
    }

  /* These are also not supported...
   * Used in glocalfileinfo.c
   */
  if (g_str_has_prefix (mime_type, "inode"))
    {
      if (g_str_has_suffix (mime_type, "directory"))
        return g_strdup ("public.directory");
      if (g_str_has_suffix (mime_type, "symlink"))
        return g_strdup ("public.symlink");
    }

  mime_str = create_cfstring_from_cstr (mime_type);
  uti_str = UTTypeCreatePreferredIdentifierForTag (kUTTagClassMIMEType, mime_str, NULL);

  CFRelease (mime_str);
  return create_cstr_from_cfstring_with_fallback (uti_str, "public.data");
}

gchar *
g_content_type_get_mime_type (const gchar *type)
{
  CFStringRef uti_str;
  CFStringRef mime_str;

  g_return_val_if_fail (type != NULL, NULL);

  /* We must match the additions above
   * so conversions back and forth work.
   */
  if (g_str_has_prefix (type, "public"))
    {
      if (g_str_has_suffix (type, ".image"))
        return g_strdup ("image/*");
      if (g_str_has_suffix (type, ".movie"))
        return g_strdup ("video/*");
      if (g_str_has_suffix (type, ".text"))
        return g_strdup ("text/*");
      if (g_str_has_suffix (type, ".audio"))
        return g_strdup ("audio/*");
      if (g_str_has_suffix (type, ".directory"))
        return g_strdup ("inode/directory");
      if (g_str_has_suffix (type, ".symlink"))
        return g_strdup ("inode/symlink");
    }

  uti_str = create_cfstring_from_cstr (type);
  mime_str = UTTypeCopyPreferredTagWithClass(uti_str, kUTTagClassMIMEType);

  CFRelease (uti_str);
  return create_cstr_from_cfstring_with_fallback (mime_str, "application/octet-stream");
}

static gboolean
looks_like_text (const guchar *data,
                 gsize         data_size)
{
  gsize i;
  guchar c;

  for (i = 0; i < data_size; i++)
    {
      c = data[i];
      if (g_ascii_iscntrl (c) && !g_ascii_isspace (c) && c != '\b')
        return FALSE;
    }
  return TRUE;
}

gchar *
g_content_type_guess (const gchar  *filename,
                      const guchar *data,
                      gsize         data_size,
                      gboolean     *result_uncertain)
{
  CFStringRef uti = NULL;
  gchar *cextension;
  CFStringRef extension;

  g_return_val_if_fail (data_size != (gsize) -1, NULL);

  if (filename && *filename)
    {
      gchar *basename = g_path_get_basename (filename);
      gchar *dirname = g_path_get_dirname (filename);
      gsize i = strlen (filename);

      if (filename[i - 1] == '/')
        {
          if (g_strcmp0 (dirname, "/Volumes") == 0)
            {
              uti = CFStringCreateCopy (NULL, kUTTypeVolume);
            }
          else if ((cextension = strrchr (basename, '.')) != NULL)
            {
              cextension++;
              extension = create_cfstring_from_cstr (cextension);
              uti = UTTypeCreatePreferredIdentifierForTag (kUTTagClassFilenameExtension,
                                                           extension, NULL);
              CFRelease (extension);

              if (CFStringHasPrefix (uti, CFSTR ("dyn.")))
                {
                  CFRelease (uti);
                  uti = CFStringCreateCopy (NULL, kUTTypeFolder);
                }
            }
          else
            {
              uti = CFStringCreateCopy (NULL, kUTTypeFolder);
            }
        }
      else
        {
          /* GTK needs this... */
          if (g_str_has_suffix (basename, ".ui"))
            {
              uti = CFStringCreateCopy (NULL, kUTTypeXML);
            }
          else if ((cextension = strrchr (basename, '.')) != NULL)
            {
              cextension++;
              extension = create_cfstring_from_cstr (cextension);
              uti = UTTypeCreatePreferredIdentifierForTag (kUTTagClassFilenameExtension,
                                                           extension, NULL);
              CFRelease (extension);
            }
          g_free (basename);
          g_free (dirname);
        }
    }
  else if (data)
    {
      if (looks_like_text (data, data_size))
        {
          if (g_str_has_prefix ((const gchar*)data, "#!/"))
            uti = CFStringCreateCopy (NULL, CFSTR ("public.script"));
          else
            uti = CFStringCreateCopy (NULL, kUTTypePlainText);
        }
    }

  if (!uti)
    {
      /* Generic data type */
      uti = CFStringCreateCopy (NULL, CFSTR ("public.data"));
      if (result_uncertain)
        *result_uncertain = TRUE;
    }

  return create_cstr_from_cfstring (uti);
}

GList *
g_content_types_get_registered (void)
{
  /* TODO: UTTypeCreateAllIdentifiersForTag? */
  return NULL;
}

gchar **
g_content_type_guess_for_tree (GFile *root)
{
  return NULL;
}
