# Path: cognitive/app/models.py
# class Data(models.Model):
#     user = models.ForeignKey(User)
#     type = models.CharField(blank=False, null=False, max_length=50)
#     file_path = models.CharField(blank=True, null=True, max_length=50)
#     columns = models.CharField(blank=True, null=True, max_length=1024)
#     created_time = models.DateTimeField(auto_now=True)
#     modified_time = models.DateTimeField(auto_now=True)
# 
#     class Meta:
#         ordering = ('-created_time',)
# 
# class User(models.Model):
#     username = models.CharField(max_length=50)
#     full_name = models.CharField(max_length=50)
#     email = models.CharField(max_length=100)
#     password = models.CharField(max_length=100)
#     token = models.CharField(max_length=100, blank=True, null=True)
#     max_experiments = models.IntegerField(default=50)
# 
#     def __str__(self):
#         return self.username
# 
#     @classmethod
#     def authenticate(cls, username_or_email, password):
#         try:
#             user = User.objects.get(username=username_or_email)
#         except:
#             try:
#                 user = User.objects.get(email=username_or_email)
#             except:
#                 return None
#         if not user.confirm_password(password):
#             return None
#         return user
# 
#     @classmethod
#     def validate(cls, username, email, password):
#         err_msg = ""
#         if not username:
#             err_msg = "Empty username field"
#             raise ValidationError(err_msg)
#         if not password:
#             err_msg = "Empty password field"
#             raise ValidationError(err_msg)
#         if not email:
#             err_msg = "Empty email field"
#             raise ValidationError(err_msg)
#         validate_email(email)
#         if User.objects.filter(username=username).count() > 0:
#             err_msg = "Username already exists"
#             raise ValidationError(err_msg)
#         if User.objects.filter(email=email).count() > 0:
#             err_msg = "Email already exists"
#             raise ValidationError(err_msg)
#         return True
# 
#     def confirm_password(self, password):
#         # TODO: password must be encrypted
#         if self.password == password:
#             return True
#         else:
#             return False
# 
#     # TODO: password encryption
# 
#     @classmethod
#     def generate_token(cls):
#         def id_generator(size=6, chars=string.ascii_uppercase + string.digits):
#             return ''.join(random.choice(chars) for _ in range(size))
#         return id_generator()
# 
#     def has_correct_token(self, token):
#         return self.token == token
# 
# Path: cognitive/app/serializers.py
# class DataSerializer(serializers.ModelSerializer):
#     class Meta:
#         model = Data
# 
# Path: cognitive/app/views.py
# def send_response(method, serializer):
#     if method == 'GET':
#         return Response(serializer.data)
#     elif method == 'POST':
#         if serializer.is_valid():
#             return Response(serializer.data, status=status.HTTP_201_CREATED)
#         else:
#             return Response(
#                 serializer.errors, status=status.HTTP_400_BAD_REQUEST)
#     elif method == 'PUT':
#         if serializer.is_valid():
#             return Response(serializer.data)
#         else:
#             return Response(
#                 serializer.errors, status=status.HTTP_400_BAD_REQUEST)
#     elif method == 'DELETE':
#         return Response(status=status.HTTP_204_NO_CONTENT)


import os.path
from datetime import datetime
from ..models import Data, User
from ..serializers import DataSerializer
from ..views import send_response
from rest_framework import viewsets

PROJECT_PATH = os.path.abspath(os.path.dirname(__name__))
FILE_UPLOAD_DIR = os.path.join(PROJECT_PATH, 'cognitive/app/uploads/')


def handle_uploaded_file(f):
    file_dir = os.path.join(FILE_UPLOAD_DIR, str(f))
    with open(file_dir, 'w+') as dest:
        for chunk in f.chunks():
            dest.write(chunk)


class DataViewSet(viewsets.ViewSet):
    # This API endpoint needs to be modified for enabling directly
    # upload any kind of data without requiring hard work on frontend

    def list(self, request):
        """
        Lists all experiments for a particular user
        ---
        """
        data = Data.objects.all()
        serializer = DataSerializer(data, many=True)
        return send_response(request.method, serializer)

    def retrieve(self, request, pk=None):
        """
        Retrieve an experiment for a particular user
        ---
        """

# Path: cognitive/app/models.py
# class Data(models.Model):
#     user = models.ForeignKey(User)
#     type = models.CharField(blank=False, null=False, max_length=50)
#     file_path = models.CharField(blank=True, null=True, max_length=50)
#     columns = models.CharField(blank=True, null=True, max_length=1024)
#     created_time = models.DateTimeField(auto_now=True)
#     modified_time = models.DateTimeField(auto_now=True)
# 
#     class Meta:
#         ordering = ('-created_time',)
# 
# class User(models.Model):
#     username = models.CharField(max_length=50)
#     full_name = models.CharField(max_length=50)
#     email = models.CharField(max_length=100)
#     password = models.CharField(max_length=100)
#     token = models.CharField(max_length=100, blank=True, null=True)
#     max_experiments = models.IntegerField(default=50)
# 
#     def __str__(self):
#         return self.username
# 
#     @classmethod
#     def authenticate(cls, username_or_email, password):
#         try:
#             user = User.objects.get(username=username_or_email)
#         except:
#             try:
#                 user = User.objects.get(email=username_or_email)
#             except:
#                 return None
#         if not user.confirm_password(password):
#             return None
#         return user
# 
#     @classmethod
#     def validate(cls, username, email, password):
#         err_msg = ""
#         if not username:
#             err_msg = "Empty username field"
#             raise ValidationError(err_msg)
#         if not password:
#             err_msg = "Empty password field"
#             raise ValidationError(err_msg)
#         if not email:
#             err_msg = "Empty email field"
#             raise ValidationError(err_msg)
#         validate_email(email)
#         if User.objects.filter(username=username).count() > 0:
#             err_msg = "Username already exists"
#             raise ValidationError(err_msg)
#         if User.objects.filter(email=email).count() > 0:
#             err_msg = "Email already exists"
#             raise ValidationError(err_msg)
#         return True
# 
#     def confirm_password(self, password):
#         # TODO: password must be encrypted
#         if self.password == password:
#             return True
#         else:
#             return False
# 
#     # TODO: password encryption
# 
#     @classmethod
#     def generate_token(cls):
#         def id_generator(size=6, chars=string.ascii_uppercase + string.digits):
#             return ''.join(random.choice(chars) for _ in range(size))
#         return id_generator()
# 
#     def has_correct_token(self, token):
#         return self.token == token
# 
# Path: cognitive/app/serializers.py
# class DataSerializer(serializers.ModelSerializer):
#     class Meta:
#         model = Data
# 
# Path: cognitive/app/views.py
# def send_response(method, serializer):
#     if method == 'GET':
#         return Response(serializer.data)
#     elif method == 'POST':
#         if serializer.is_valid():
#             return Response(serializer.data, status=status.HTTP_201_CREATED)
#         else:
#             return Response(
#                 serializer.errors, status=status.HTTP_400_BAD_REQUEST)
#     elif method == 'PUT':
#         if serializer.is_valid():
#             return Response(serializer.data)
#         else:
#             return Response(
#                 serializer.errors, status=status.HTTP_400_BAD_REQUEST)
#     elif method == 'DELETE':
#         return Response(status=status.HTTP_204_NO_CONTENT)


# Path: cognitive/app/api/data.py
import os.path
from datetime import datetime
from ..models import Data, User
from ..serializers import DataSerializer
from ..views import send_response
from rest_framework import viewsets


PROJECT_PATH = os.path.abspath(os.path.dirname(__name__))
FILE_UPLOAD_DIR = os.path.join(PROJECT_PATH, 'cognitive/app/uploads/')


def handle_uploaded_file(f):
    file_dir = os.path.join(FILE_UPLOAD_DIR, str(f))
    with open(file_dir, 'w+') as dest:
        for chunk in f.chunks():
            dest.write(chunk)


class DataViewSet(viewsets.ViewSet):
    # This API endpoint needs to be modified for enabling directly
    # upload any kind of data without requiring hard work on frontend

    def list(self, request):
        """
        Lists all experiments for a particular user
        ---
        """
        data = Data.objects.all()
        serializer = DataSerializer(data, many=True)
        return send_response(request.method, serializer)

    def retrieve(self, request, pk=None):
        """
        Retrieve an experiment for a particular user
        ---
        """

        data = Data.objects.get(pk=pk)