#!/usr/bin/env python
# -*- coding: utf-8 -*-

# This work was created by participants in the DataONE project, and is
# jointly copyrighted by participating institutions in DataONE. For
# more information on DataONE, see our web site at http://dataone.org.
#
#   Copyright 2009-2012 DataONE
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
''':mod:`views.internal`
========================

:Synopsis:
  Functionality that is not part of the DataONE Member Node API yet is designed
  to be available when the MN is in production.

:Author: DataONE (Dahl)
'''
# Stdlib.
import ctypes
import datetime
import os
import platform

# Django.
import django
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render_to_response
from django.db.models import Avg, Count, Sum
from django.conf import settings

# DataONE APIs.
import d1_common.const
import d1_common.date_time
import d1_common.types.exceptions
import d1_common.types.generated.dataoneTypes as dataoneTypes

# App.
import mn.auth
import mn.db_filter
import mn.event_log
import mn.models
import mn.psycopg_adapter
import mn.sysmeta_store
import mn.sysmeta_validate
import mn.util
import mn.view_asserts
import mn.view_shared
import service


def home(request):
  '''Home page. Root of web server should redirect to here.'''
  if request.path.endswith('/'):
    return HttpResponseRedirect(request.path[:-1])

  gmn_version = mn.__version__
  django_version = ', '.join(map(str, django.VERSION))

  n_science_objects = group(mn.models.ScienceObject.objects.count())

  avg_sci_data_size_bytes = mn.models.ScienceObject.objects\
    .aggregate(Avg('size'))['size__avg'] or 0
  avg_sci_data_size = group(int(avg_sci_data_size_bytes))

  n_objects_by_format_id = mn.models.ScienceObject.objects.values(
    'format', 'format__format_id'
  ).annotate(dcount=Count('format'))

  n_connections_total = group(mn.models.EventLog.objects.count())

  n_connections_in_last_hour = group(
    mn.models.EventLog.objects.filter(
      date_logged__gte=datetime.datetime.utcnow() - datetime.timedelta(hours=1)
    ).count()
  )

  n_unique_subjects = group(mn.models.PermissionSubject.objects.count())

  n_storage_used = mn.models.ScienceObject.objects\
    .aggregate(Sum('size'))['size__sum'] or 0
  n_storage_free = get_free_space(settings.MEDIA_ROOT)
  storage_space = '{0} GiB / {1} GiB'.format(
    n_storage_used / 1024**3, n_storage_free / 1024**3
  )

  n_permissions = group(mn.models.Permission.objects.count())

  server_time = datetime.datetime.utcnow()

  node_identifier = settings.NODE_IDENTIFIER
  node_name = settings.NODE_NAME
  node_description = settings.NODE_DESCRIPTION

  return render_to_response(
    'home.html', locals(),
    content_type=d1_common.const.CONTENT_TYPE_XHTML
  )

# Util.


def get_free_space(folder):
  '''Return folder/drive free space (in bytes)
  '''
  if platform.system() == 'Windows':
    free_bytes = ctypes.c_ulonglong(0)
    ctypes.windll.kernel32.GetDiskFreeSpaceExW(
      ctypes.c_wchar_p(folder), None, None, ctypes.pointer(free_bytes)
    )
    return free_bytes.value
  else:
    return os.statvfs(folder).f_bfree * os.statvfs(folder).f_frsize


def group(n, sep=','):
  '''Group digits in number by thousands'''
  # Python 2.7 has support for grouping (the "," format specifier)
  s = str(abs(n))[::-1]
  groups = []
  i = 0
  while i < len(s):
    groups.append(s[i:i + 3])
    i += 3
  retval = sep.join(groups)[::-1]
  if n < 0:
    return '-%s' % retval
  else:
    return retval

@@ -1610,20 +1610,19 @@
 sysmeta_
-stor
+fil
 e%0Aimport
@@ -1663,24 +1663,30 @@
 l%0Aimport mn.
+views.
 view_asserts
@@ -1704,30 +1704,19 @@
 view
-_shared%0Aimport service
+s.view_util
 %0A%0A%0Ad
@@ -1735,19 +1735,19 @@
 est):%0A  
-'''
+%22%22%22
 Home pag
@@ -1792,19 +1792,19 @@
 to here.
-'''
+%22%22%22
 %0A  if re
@@ -1982,37 +1982,45 @@
 ience_objects = 
-group
+'%7B:,%7D'.format
 (mn.models.Scien
@@ -2175,21 +2175,29 @@
 _size = 
-group
+'%7B:,%7D'.format
 (int(avg
@@ -2383,21 +2383,29 @@
 total = 
-group
+'%7B:,%7D'.format
 (mn.mode
@@ -2465,21 +2465,29 @@
 _hour = 
-group
+'%7B:,%7D'.format
 (%0A    mn
@@ -2636,29 +2636,37 @@
 _subjects = 
-group
+'%7B:,%7D'.format
 (mn.models.P
@@ -2817,16 +2817,17 @@
 _free = 
+_
 get_free
@@ -2876,11 +2876,11 @@
 e = 
+u
 '%7B
-0
 %7D Gi
@@ -2884,17 +2884,16 @@
  GiB / %7B
-1
 %7D GiB'.f
@@ -2977,21 +2977,29 @@
 sions = 
-group
+'%7B:,%7D'.format
 (mn.mode
@@ -3714,344 +3714,4 @@
 ze%0A%0A
-%0Adef group(n, sep=','):%0A  '''Group digits in number by thousands'''%0A  # Python 2.7 has support for grouping (the %22,%22 format specifier)%0A  s = str(abs(n))%5B::-1%5D%0A  groups = %5B%5D%0A  i = 0%0A  while i %3C len(s):%0A    groups.append(s%5Bi:i + 3%5D)%0A    i += 3%0A  retval = sep.join(groups)%5B::-1%5D%0A  if n %3C 0:%0A    return '-%25s' %25 retval%0A  else:%0A    return retval%0A

Remove custom function for thousands grouping of integers