<commit_before># Copyright 2014 The University of Edinburgh
#
# 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.

from django.contrib.auth.models import User, Group
from models import WorkspaceItem, Workspace, PESig, FunctionSig, LiteralSig, PEImplementation, FnImplementation, RegistryUserGroup, Connection, FunctionParameter
from django.contrib.auth.models import User
from django.contrib.auth.models import Group

from rest_framework import serializers
from vercereg.utils import get_base_rest_uri

##############################################################################
class UserSerializer(serializers.HyperlinkedModelSerializer):
  groups = serializers.SerializerMethodField('get_reg_groups')

  def get_reg_groups(self, obj):
    toret = []
    # print '>> ', str(obj.groups)
    request = self.context.get('request')
    for v in obj.groups.values():
      # FIXME: Constructs the URL manually, via the request, which is not advisable (insecure and not very robust)
      group_id = v['id']
      g = Group.objects.get(id=group_id)
      try:
        rug_instance = RegistryUserGroup.objects.get(group=g)
        rug = get_base_rest_uri(request) + 'registryusergroups/' + str(rug_instance.id) + '/'
        toret.append(rug)
      except RegistryUserGroup.DoesNotExist:
        pass
    return toret

  def restore_object(self, attrs, instance=None):
    user = super(UserSerializer, self).restore_object(attrs, instance)
    user.set_password(attrs['password'])
    return user

  class Meta:
    model = User
    fields = ('url', 'username', 'email', 'first_name', 'last_name', 'password', 'groups', 'owns')
    write_only_fields = ('password',)
    read_only_fields = ('owns',)

##############################################################################
class UserUpdateSerializer(serializers.HyperlinkedModelSerializer):
  class Meta:
    model = User
    fields = ('username', 'email', 'first_name', 'last_name', 'password', 'groups', 'owns',)
    write_only_fields = ('password',)
    read_only_fields = ('username',)

  def restore_object(self, attrs, instance=None):
    user = super(UserUpdateSerializer, self).restore_object(attrs, instance)
    user.set_password(attrs['password'])
    return user

##############################################################################
class RegistryUserGroupSerializer(serializers.HyperlinkedModelSerializer):
  group_name = serializers.CharField(source='get_group_name')#, read_only=True)
  owner_username = serializers.CharField(source='get_owner_username', read_only=True)

  class Meta:
    model = RegistryUserGroup
    fields = ('url', 'group_name', 'owner_username', 'group', 'owner', 'description',)
    read_only_fields = ('group', 'owner')

##############################################################################

# class AdminRegistryUserGroupSerializer(serializers.HyperlinkedModelSerializer):
#   group_name = serializers.CharField(source='get_group_name')#, read_only=True)
#   owner_username = serializers.CharField(source='get_owner_username', read_only=True)
#
#   class Meta:
#     model = RegistryUserGroup
#     fields = ('url', 'group_name', 'owner_username', 'group', 'owner', 'description')
#     read_only_fields = ('group', )


##############################################################################
class GroupSerializer(serializers.HyperlinkedModelSerializer):
  class Meta:
    model = Group
    fields = ('name',)

##############################################################################
class PEImplementationSerializer(serializers.HyperlinkedModelSerializer):
  class Meta:
    model = PEImplementation
    fields = ('description', 'code', 'parent_sig', 'pckg', 'name', 'user', 'workspace')
    read_only_fields = ('user', 'creation_date',)

##############################################################################
class FnImplementationSerializer(serializers.HyperlinkedModelSerializer):
  class Meta:
    model = FnImplementation
    fields = ('description', 'code', 'parent_sig', 'pckg', 'name', 'user', 'workspace')
    read_only_fields = ('user', 'creation_date',)

##############################################################################
class WorkspaceSerializer(serializers.HyperlinkedModelSerializer):
  class Meta:
    model = Workspace
    depth = 0
    fields = ('id', 'url', 'name', 'owner', 'description', 'creation_date')
    read_only_fields = ('owner', 'creation_date',)

##############################################################################
class WorkspaceDeepSerializer(serializers.HyperlinkedModelSerializer):

  pes = serializers.CharField(source='get_pesigs')
  functions = serializers.CharField(source='get_fnsigs')
  literals = serializers.CharField(source='get_literalsigs')
  peimplementations = serializers.CharField(source='get_peimplementations')
  fnimplementations = serializers.CharField(source='get_fnimplementations')

  class Meta:
    model = Workspace
    # TODO (nice-to-have) revisit the depth issue, user serialization is not good enough - disabled for now.
    depth = 0
    read_only_fields = ('owner', 'creation_date')

  def transform_pes(self, obj, value):
    request = self.context.get('request')
    pes = obj.pesig_set.get_queryset()
    return map(lambda p: get_base_rest_uri(request) + 'pes/' + str(p.id), pes)

  def transform_functions(self, obj, value):
    request = self.context.get('request')
    fns = obj.functionsig_set.get_queryset()
    return map(lambda p: get_base_rest_uri(request) + 'functions/' + str(p.id), fns)

  def transform_literals(self, obj, value):
    request = self.context.get('request')
    lits = obj.literalsig_set.get_queryset()
    return map(lambda p: get_base_rest_uri(request) + 'literals/' + str(p.id), lits)

  def transform_peimplementations(self, obj, value):
    request = self.context.get('request')
    peimpls = obj.peimpls.get_queryset()
    return map(lambda p: get_base_rest_uri(request) + 'peimpls/' + str(p.id), peimpls)

  def transform_fnimplementations(self, obj, value):
    request = self.context.get('request')
    fnimpls = obj.fnimpls.get_queryset()
    return map(lambda p: get_base_rest_uri(request) + 'fnimpls/' + str(p.id), fnimpls)


##############################################################################
class PESigSerializer(serializers.HyperlinkedModelSerializer):
  class Meta:
    model = PESig
    fields = ('url', 'id', 'workspace', 'pckg', 'name', 'user', 'description', 'connections', 'creation_date', 'peimpls')
    read_only_fields = ('user', 'creation_date', )

##############################################################################
class ConnectionSerializer(serializers.HyperlinkedModelSerializer):
  class Meta:
    model = Connection

class FunctionParameterSerializer(serializers.HyperlinkedModelSerializer):
  class Meta:
    model = FunctionParameter

##############################################################################
class FunctionSigSerializer(serializers.HyperlinkedModelSerializer):
  #implementations = serializers.WritableField(source='fnimplementation_set', required=False)
  class Meta:
    model = FunctionSig
    fields = ('url', 'id', 'workspace', 'pckg', 'name', 'user', 'description', 'creation_date', 'return_type', 'parameters', 'fnimpls')
    read_only_fields = ('user', 'creation_date', )

##############################################################################
class LiteralSigSerializer(serializers.HyperlinkedModelSerializer):
  class Meta:
    model = LiteralSig<commit_msg>bug fix<commit_after># Copyright 2014 The University of Edinburgh
#
# 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.

from django.contrib.auth.models import User, Group
from models import WorkspaceItem, Workspace, PESig, FunctionSig, LiteralSig, PEImplementation, FnImplementation, RegistryUserGroup, Connection, FunctionParameter
from django.contrib.auth.models import User
from django.contrib.auth.models import Group

from rest_framework import serializers
from vercereg.utils import get_base_rest_uri

##############################################################################
class UserSerializer(serializers.HyperlinkedModelSerializer):
  groups = serializers.SerializerMethodField('get_reg_groups')

  def get_reg_groups(self, obj):
    toret = []
    # print '>> ', str(obj.groups)
    request = self.context.get('request')
    for v in obj.groups.values():
      # FIXME: Constructs the URL manually, via the request, which is not advisable (insecure and not very robust)
      group_id = v['id']
      g = Group.objects.get(id=group_id)
      try:
        rug_instance = RegistryUserGroup.objects.get(group=g)
        rug = get_base_rest_uri(request) + 'registryusergroups/' + str(rug_instance.id) + '/'
        toret.append(rug)
      except RegistryUserGroup.DoesNotExist:
        pass
    return toret

  def restore_object(self, attrs, instance=None):
    user = super(UserSerializer, self).restore_object(attrs, instance)
    user.set_password(attrs['password'])
    return user

  class Meta:
    model = User
    fields = ('url', 'username', 'email', 'first_name', 'last_name', 'password', 'groups', 'owns')
    write_only_fields = ('password',)
    read_only_fields = ('owns',)

##############################################################################
class UserUpdateSerializer(serializers.HyperlinkedModelSerializer):
  class Meta:
    model = User
    fields = ('username', 'email', 'first_name', 'last_name', 'password', 'groups', 'owns',)
    write_only_fields = ('password',)
    read_only_fields = ('username',)

  def restore_object(self, attrs, instance=None):
    user = super(UserUpdateSerializer, self).restore_object(attrs, instance)
    user.set_password(attrs['password'])
    return user

##############################################################################
class RegistryUserGroupSerializer(serializers.HyperlinkedModelSerializer):
  group_name = serializers.CharField(source='get_group_name')#, read_only=True)
  owner_username = serializers.CharField(source='get_owner_username', read_only=True)

  class Meta:
    model = RegistryUserGroup
    fields = ('url', 'group_name', 'owner_username', 'group', 'owner', 'description',)
    read_only_fields = ('group', 'owner')

##############################################################################

# class AdminRegistryUserGroupSerializer(serializers.HyperlinkedModelSerializer):
#   group_name = serializers.CharField(source='get_group_name')#, read_only=True)
#   owner_username = serializers.CharField(source='get_owner_username', read_only=True)
#
#   class Meta:
#     model = RegistryUserGroup
#     fields = ('url', 'group_name', 'owner_username', 'group', 'owner', 'description')
#     read_only_fields = ('group', )


##############################################################################
class GroupSerializer(serializers.HyperlinkedModelSerializer):
  class Meta:
    model = Group
    fields = ('name',)

##############################################################################
class PEImplementationSerializer(serializers.HyperlinkedModelSerializer):
  class Meta:
    model = PEImplementation
    fields = ('description', 'code', 'parent_sig', 'pckg', 'name', 'user', 'workspace')
    read_only_fields = ('user', 'creation_date',)

##############################################################################
class FnImplementationSerializer(serializers.HyperlinkedModelSerializer):
  class Meta:
    model = FnImplementation
    fields = ('description', 'code', 'parent_sig', 'pckg', 'name', 'user', 'workspace')
    read_only_fields = ('user', 'creation_date',)

##############################################################################
class WorkspaceSerializer(serializers.HyperlinkedModelSerializer):
  class Meta:
    model = Workspace
    depth = 0
    fields = ('id', 'url', 'name', 'owner', 'description', 'creation_date')
    read_only_fields = ('owner', 'creation_date',)

##############################################################################
class WorkspaceDeepSerializer(serializers.HyperlinkedModelSerializer):

  pes = serializers.CharField(source='get_pesigs')
  functions = serializers.CharField(source='get_fnsigs')
  literals = serializers.CharField(source='get_literalsigs')
  peimplementations = serializers.CharField(source='get_peimplementations')
  fnimplementations = serializers.CharField(source='get_fnimplementations')

  class Meta:
    model = Workspace
    # TODO (nice-to-have) revisit the depth issue, user serialization is not good enough - disabled for now.
    depth = 0
    read_only_fields = ('owner', 'creation_date')

  def transform_pes(self, obj, value):
    request = self.context.get('request')
    pes = obj.pesig_set.get_queryset()
    return map(lambda p: get_base_rest_uri(request) + 'pes/' + str(p.id), pes)

  def transform_functions(self, obj, value):
    request = self.context.get('request')
    fns = obj.functionsig_set.get_queryset()
    return map(lambda p: get_base_rest_uri(request) + 'functions/' + str(p.id), fns)

  def transform_literals(self, obj, value):
    request = self.context.get('request')
    lits = obj.literalsig_set.get_queryset()
    return map(lambda p: get_base_rest_uri(request) + 'literals/' + str(p.id), lits)

  def transform_peimplementations(self, obj, value):
    request = self.context.get('request')
    peimpls = obj.peimplementation_set.get_queryset()
    return map(lambda p: get_base_rest_uri(request) + 'peimpls/' + str(p.id), peimpls)

  def transform_fnimplementations(self, obj, value):
    request = self.context.get('request')
    fnimpls = obj.fnimplementation_set.get_queryset()
    return map(lambda p: get_base_rest_uri(request) + 'fnimpls/' + str(p.id), fnimpls)


##############################################################################
class PESigSerializer(serializers.HyperlinkedModelSerializer):
  class Meta:
    model = PESig
    fields = ('url', 'id', 'workspace', 'pckg', 'name', 'user', 'description', 'connections', 'creation_date', 'peimpls')
    read_only_fields = ('user', 'creation_date', )

##############################################################################
class ConnectionSerializer(serializers.HyperlinkedModelSerializer):
  class Meta:
    model = Connection

class FunctionParameterSerializer(serializers.HyperlinkedModelSerializer):
  class Meta:
    model = FunctionParameter

##############################################################################
class FunctionSigSerializer(serializers.HyperlinkedModelSerializer):
  #implementations = serializers.WritableField(source='fnimplementation_set', required=False)
  class Meta:
    model = FunctionSig
    fields = ('url', 'id', 'workspace', 'pckg', 'name', 'user', 'description', 'creation_date', 'return_type', 'parameters', 'fnimpls')
    read_only_fields = ('user', 'creation_date', )

##############################################################################
class LiteralSigSerializer(serializers.HyperlinkedModelSerializer):
  class Meta:
    model = LiteralSig
{'fraction_non_alphanumeric': 0.23180626638372237, 'fraction_numerical': 0.0012482836100362001, 'mean_word_length': 5.978658536585366, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '955380', 'n_tokens_mistral': 4430, 'n_tokens_neox': 4259, 'n_words': 1004}