import logging
import os

from swagger_server.database.models.people import FabricPeople
from swagger_server.database.models.prefs_and_profiles import ProfilesKeywords, ProfilesReferences
from swagger_server.database.models.projects import FabricProjects, ProjectsTags
from swagger_server.models.inline_response2003 import InlineResponse2003
from swagger_server.models.inline_response2004 import InlineResponse2004
from swagger_server.models.inline_response2005 import InlineResponse2005
from swagger_server.models.model200_ok_paginated_links import Model200OkPaginatedLinks
from swagger_server.models.people import People
from swagger_server.models.preferences_profile_projects import PreferencesProfileProjects
from swagger_server.models.preferences_projects import PreferencesProjects
from swagger_server.models.profile_projects_one import ProfileProjectsOne, ProfileProjectsOneReferences
from swagger_server.models.profile_projects_self import ProfileProjectsSelf
from swagger_server.models.projects import Projects, ProjectMemberships
from swagger_server.models.projects_one import ProjectsOne
from swagger_server.models.projects_self import ProjectsSelf
from swagger_server.response_code.local_people_controller import get_people_preferences

logger = logging.getLogger(__name__)

# Constants
_SERVER_URL = os.getenv('CORE_API_SERVER_URL', '')
_500_ERROR = "Oops!!: Something unexpected has occurred, please try again (patch_people_self)"


# Preferences
def get_projects_preferences(fab_project: FabricProjects = None) -> object:
    """
    Project Preferences - default = True
    - is_public: <booL>
    - show_profile: <booL>
    - show_project_members: <booL>
    - show_project_owners: <booL>
    - show_publications: <booL>
    """
    prefs = {p.key: p.value for p in fab_project.preferences}
    preferences = PreferencesProjects(**prefs)
    return preferences


def get_profile_projects_preferences(fab_project: FabricProjects = None) -> PreferencesProfileProjects:
    """
    Profile People Preferences - default = True
    - show_award_information: <booL>
    - show_goals: <booL>
    - show_keywords: <booL>
    - show_notebooks: <booL>
    - show_project_status: <booL>
    - show_purpose: <booL>
    - show_references: <bool>
    """
    prefs = {p.key: p.value for p in fab_project.profile.preferences}
    preferences = PreferencesProfileProjects(**prefs)
    return preferences


# Profiles
def get_profile_projects_one(fab_project: FabricProjects = None) -> ProfileProjectsOne:
    """
    All fields are optional (preference based)
    - award_information: <string>
    - goals: <string>
    - keywords: []
    - notebooks: []
    - project_status: <string>
    - purpose: <string>
    - references: []
    """
    profile = ProfileProjectsOne()
    fab_profile = fab_project.profile
    prefs = get_profile_projects_preferences(fab_project=fab_project)
    profile.award_information = fab_profile.award_information if prefs.__getattribute__(
        'show_award_information') else None
    profile.goals = fab_profile.goals if prefs.__getattribute__('show_goals') else None
    profile.keywords = get_projects_profile_keywords(
        fab_project=fab_project) if prefs.__getattribute__('show_keywords') else None
    profile.notebooks = get_projects_profile_notebooks(
        fab_project=fab_project) if prefs.__getattribute__('show_notebooks') else None
    profile.project_status = fab_profile.project_status if prefs.__getattribute__('show_project_status') else None
    profile.purpose = fab_profile.purpose if prefs.__getattribute__('show_purpose') else None
    profile.references = get_projects_profile_references(
        fab_project=fab_project) if prefs.__getattribute__('show_references') else None
    return profile


def get_profile_projects_self(fab_project: FabricProjects = None) -> ProfileProjectsSelf:
    """
    All fields are optional (preference based)
    - award_information: <string>
    - goals: <string>
    - keywords: []
    - notebooks: []
    - project_status: <string>
    - purpose: <string>
    - references: []
    """
    profile = ProfileProjectsSelf()
    fab_profile = fab_project.profile
    profile.award_information = fab_profile.award_information
    profile.goals = fab_profile.goals
    profile.keywords = get_projects_profile_keywords(fab_project=fab_project)
    profile.notebooks = get_projects_profile_notebooks(fab_project=fab_project)
    profile.preferences = get_profile_projects_preferences(fab_project=fab_project)
    profile.project_status = fab_profile.project_status
    profile.purpose = fab_profile.purpose
    profile.references = get_projects_profile_references(fab_project=fab_project)
    return profile


# Keywords - Projects Profile
def get_projects_profile_keywords(fab_project: FabricProjects = None) -> [ProfilesKeywords]:
    keywords = ProfilesKeywords.query.filter(
        ProfilesKeywords.profile_id == fab_project.profile.id
    )
    response = []
    for k in keywords:
        kw = ProfilesKeywords()
        kw.keyword = k.keyword
        response.append(kw)
    return response


# Notebooks - Projects Profile
def get_projects_profile_notebooks(fab_project: FabricProjects = None) -> [object]:
    notebooks = []
    return notebooks


# References - Projects Profile
def get_projects_profile_references(fab_project: FabricProjects = None) -> [ProfileProjectsOneReferences]:
    references = ProfilesReferences.query.filter_by(profile_id=fab_project.profile.id)
    response = []
    for r in references:
        ref = ProfilesReferences()
        ref.description = r.description
        ref.url = r.url
        response.append(ref)
    return response


# Publications - Projects
def get_projects_publications(fab_project: FabricProjects = None) -> [object]:
    publications = []
    return publications


# Keywords - Project Profile
def get_projects_tags(fab_project: FabricProjects = None) -> [str]:
    tags = ProjectsTags.query.filter_by(projects_id=fab_project.id)
    response = []
    for t in tags:
        response.append(t.tag)
    return response


# Creators, Owners and Members - Projects
def get_projects_personnel(fab_project: FabricProjects = None, personnel_type: str = None) -> [People]:
    """
    * Denotes required fields
    - email: <string>
    - * name: <string>
    - * uuid: <string>
    """
    personnel = []
    if personnel_type == 'creators':
        personnel = fab_project.project_creators
    elif personnel_type == 'owners':
        personnel = fab_project.project_owners
    elif personnel_type == 'members':
        personnel = fab_project.project_members
    personnel_data = []
    for p in personnel:
        # get preferences (show_email)
        prefs = get_people_preferences(fab_person=FabricPeople.query.filter_by(uuid=p.uuid).one_or_none())
        # set person attributes
        person = People()
        person.email = p.preferred_email if prefs.__getattribute__('show_email') else None
        person.name = p.display_name
        person.uuid = p.uuid
        # add person to personnel_data
        personnel_data.append(person)

    return personnel_data


# Memberships - Projects
def get_projects_memberships(fab_project: FabricProjects = None) -> ProjectMemberships:
    response = ProjectMemberships()

    return response


# Projects
def get_projects(search: str = None, offset: int = 0,
                 limit: int = int(os.getenv('CORE_API_DEFAULT_LIMIT'))) -> InlineResponse2003:
    """
    Return all for public projects (private depends on membership of user)
    - "created": "string",
    - "description": "string",
    - "facility": "string",
    - "is_public": true,
    - "memberships": {
        "project_creator": false,
        "project_member": false,
        "project_owner": false
      },
    - "name": "string",
    - "uuid": "string"
    """
    # set page to retrieve
    _page = int((offset + limit) / limit)
    # get paginated search results
    if search:
        data_page = FabricProjects.query.filter(
            (FabricProjects.active.is_(True)) &
            (FabricProjects.name.ilike("%" + search + "%"))
        ).order_by(FabricProjects.name).paginate(page=_page, per_page=limit, error_out=False)
    else:
        data_page = FabricProjects.query.filter(
            FabricProjects.active.is_(True)
        ).order_by(FabricProjects.name).paginate(
            page=_page, per_page=limit, error_out=False)
    # set people data
    projects = InlineResponse2003()
    projects.data = []
    for item in data_page.items:
        # set project attributes
        project = Projects()
        project.created = str(item.created)
        project.description = item.description
        project.facility = item.facility
        # TODO set is_public attribute
        project.is_public = True
        # TODO set membership_type object
        project.memberships = get_projects_memberships()
        project.name = item.name
        project.uuid = item.uuid
        projects.data.append(project)
    # set links
    projects.links = Model200OkPaginatedLinks()
    _URL_OFFSET_LIMIT = '{0}offset={1}&limit={2}'
    base = '{0}/projects?'.format(_SERVER_URL) if not search else '{0}/projects?search={1}&'.format(_SERVER_URL, search)
    projects.links.first = _URL_OFFSET_LIMIT.format(base, 0, limit) if data_page.pages > 0 else None
    projects.links.last = _URL_OFFSET_LIMIT.format(base, int((data_page.pages - 1) * limit),
                                                   limit) if data_page.pages > 0 else None
    projects.links.next = _URL_OFFSET_LIMIT.format(base, int(offset + limit), limit) if data_page.has_next else None
    projects.links.prev = _URL_OFFSET_LIMIT.format(base, int(offset - limit), limit) if data_page.has_prev else None
    # set offset, limit and size
    projects.limit = limit
    projects.offset = offset
    projects.size = len(projects.data)

    return projects


def get_projects_one(fab_project: FabricProjects = None) -> InlineResponse2004:
    """
    * Denotes required fields
    - * active: <bool>
    - * created: <string>
    - * description: <string>
    - * facility: <string>
    - * is_public: <bool>
    - * memberships: {
        - project_creator: <booL>
        - project_member: <bool>
        - project_owner: <bool>
      }
    - * modified: <string>
    - * name: <string>
    - profile: {
        - award_information: <string>
        - goals: <string>
        - keywords: []
        - notebooks: []
        - project_status: <string>
        - purpose: <string>
        - references: []
      }
    - * project_creators: []
    - project_members: []
    - project_owners: []
    - publications: []
    - * tags: []
    - * uuid: <string>
    """
    # required attributes
    project = ProjectsOne()
    project.active = fab_project.active
    project.created = str(fab_project.created)
    project.description = fab_project.description
    project.facility = fab_project.facility
    # TODO get memberships from user making request
    project.memberships = get_projects_memberships(fab_project=fab_project)
    project.modified = str(fab_project.modified)
    project.name = fab_project.name
    project.project_creators = get_projects_personnel(fab_project=fab_project, personnel_type='creators')
    project.tags = get_projects_tags(fab_project=fab_project)
    project.uuid = fab_project.uuid

    # optional attributes by preference
    prefs = get_projects_preferences(fab_project=fab_project)
    # TODO get is_public from preferences
    project.is_public = prefs.__getattribute__('is_public')
    project.profile = get_profile_projects_one(
        fab_project=fab_project) if prefs.__getattribute__('show_profile') else None
    project.project_owners = get_projects_personnel(
        fab_project=fab_project, personnel_type='owners') if prefs.__getattribute__('show_project_owners') else None
    project.project_members = get_projects_personnel(
        fab_project=fab_project, personnel_type='members') if prefs.__getattribute__('show_project_members') else None
    project.publications = get_projects_publications(
        fab_project=fab_project) if prefs.__getattribute__('show_publications') else None

    # project_one object
    project_one = InlineResponse2004()
    project_one.data = []
    project_one.data.append(project)

    return project_one


def get_projects_self(fab_project: FabricProjects = None) -> InlineResponse2005:
    """
    All fields are required
    - active: <bool>
    - created: <string>
    - description: <string>
    - facility: <string>
    - is_public: <bool>
    - memberships: {
        - project_creator: <booL>
        - project_member: <bool>
        - project_owner: <bool>
      }
    - modified: <string>
    - name: <string>
    - preferences: {
        - is_public: <bool>
        - show_profile: <bool>
        - show_project_members: <bool>
        - show_project_owners: <bool>
        - show_publications: <bool>
      }
    - profile: {
        - award_information: <string>
        - goals: <string>
        - keywords: []
        - notebooks: []
        - preferences: {
            - show_award_information: <bool>,
            - show_goals: <bool>
            - show_keywords: <bool>
            - show_notebooks: <bool>
            - show_project_status: <bool>
            - show_purpose: <bool>
            - show_references: <bool>
          }
        - project_status: <string>
        - purpose: <string>
        - references: []
      }
    - project_creators: []
    - project_members: []
    - project_owners: []
    - publications: []
    - tags: []
    - uuid: <string>
    """
    # required attributes
    project = ProjectsSelf()
    project.active = fab_project.active
    project.created = str(fab_project.created)
    project.description = fab_project.description
    project.facility = fab_project.facility
    # TODO get is_public from preferences
    prefs = get_projects_preferences(fab_project=fab_project)
    project.is_public = prefs.__getattribute__('is_public')
    # TODO get memberships from user making request
    project.memberships = get_projects_memberships(fab_project=fab_project)
    project.modified = str(fab_project.modified)
    project.name = fab_project.name
    project.preferences = prefs
    project.profile = get_profile_projects_self(fab_project=fab_project)
    project.project_creators = get_projects_personnel(fab_project=fab_project, personnel_type='creators')
    project.project_members = get_projects_personnel(fab_project=fab_project, personnel_type='members')
    project.project_owners = get_projects_personnel(fab_project=fab_project, personnel_type='owners')
    project.publications = get_projects_publications(fab_project=fab_project)
    project.tags = get_projects_tags(fab_project=fab_project)
    project.uuid = fab_project.uuid

    # project_self object
    project_self = InlineResponse2005()
    project_self.data = []
    project_self.data.append(project)

    return project_self

import logging
import os

from swagger_server.database.models.people import FabricPeople
from swagger_server.database.models.prefs_and_profiles import ProfilesKeywords, ProfilesReferences
from swagger_server.database.models.projects import FabricProjects, ProjectsTags
from swagger_server.models.inline_response2003 import InlineResponse2003
from swagger_server.models.inline_response2004 import InlineResponse2004
from swagger_server.models.inline_response2005 import InlineResponse2005
from swagger_server.models.model200_ok_paginated_links import Model200OkPaginatedLinks
from swagger_server.models.people import People
from swagger_server.models.preferences_profile_projects import PreferencesProfileProjects
from swagger_server.models.preferences_projects import PreferencesProjects
from swagger_server.models.profile_projects_one import ProfileProjectsOne, ProfileProjectsOneReferences
from swagger_server.models.profile_projects_self import ProfileProjectsSelf
from swagger_server.models.projects import Projects, ProjectMemberships
from swagger_server.models.projects_one import ProjectsOne
from swagger_server.models.projects_self import ProjectsSelf
from swagger_server.response_code.local_people_controller import get_people_preferences

logger = logging.getLogger(__name__)

# Constants
_SERVER_URL = os.getenv('CORE_API_SERVER_URL', '')
_500_ERROR = "Oops!!: Something unexpected has occurred, please try again (patch_people_self)"


# Preferences
def get_projects_preferences(fab_project: FabricProjects = None) -> object:
    """
    Project Preferences - default = True
    - is_public: <booL>
    - show_profile: <booL>
    - show_project_members: <booL>
    - show_project_owners: <booL>
    - show_publications: <booL>
    """
    prefs = {p.key: p.value for p in fab_project.preferences}
    preferences = PreferencesProjects(**prefs)
    return preferences


def get_profile_projects_preferences(fab_project: FabricProjects = None) -> PreferencesProfileProjects:
    """
    Profile People Preferences - default = True
    - show_award_information: <booL>
    - show_goals: <booL>
    - show_keywords: <booL>
    - show_notebooks: <booL>
    - show_project_status: <booL>
    - show_purpose: <booL>
    - show_references: <bool>
    """
    prefs = {p.key: p.value for p in fab_project.profile.preferences}
    preferences = PreferencesProfileProjects(**prefs)
    return preferences


# Profiles
def get_profile_projects_one(fab_project: FabricProjects = None) -> ProfileProjectsOne:
    """
    All fields are optional (preference based)
    - award_information: <string>
    - goals: <string>
    - keywords: []
    - notebooks: []
    - project_status: <string>
    - purpose: <string>
    - references: []
    """
    profile = ProfileProjectsOne()
    fab_profile = fab_project.profile
    prefs = get_profile_projects_preferences(fab_project=fab_project)
    profile.award_information = fab_profile.award_information if prefs.__getattribute__(
        'show_award_information') else None
    profile.goals = fab_profile.goals if prefs.__getattribute__('show_goals') else None
    profile.keywords = get_projects_profile_keywords(
        fab_project=fab_project) if prefs.__getattribute__('show_keywords') else None
    profile.notebooks = get_projects_profile_notebooks(
        fab_project=fab_project) if prefs.__getattribute__('show_notebooks') else None
    profile.project_status = fab_profile.project_status if prefs.__getattribute__('show_project_status') else None
    profile.purpose = fab_profile.purpose if prefs.__getattribute__('show_purpose') else None
    profile.references = get_projects_profile_references(
        fab_project=fab_project) if prefs.__getattribute__('show_references') else None
    return profile


def get_profile_projects_self(fab_project: FabricProjects = None) -> ProfileProjectsSelf:
    """
    All fields are optional (preference based)
    - award_information: <string>
    - goals: <string>
    - keywords: []
    - notebooks: []
    - project_status: <string>
    - purpose: <string>
    - references: []
    """
    profile = ProfileProjectsSelf()
    fab_profile = fab_project.profile
    profile.award_information = fab_profile.award_information
    profile.goals = fab_profile.goals
    profile.keywords = get_projects_profile_keywords(fab_project=fab_project)
    profile.notebooks = get_projects_profile_notebooks(fab_project=fab_project)
    profile.preferences = get_profile_projects_preferences(fab_project=fab_project)
    profile.project_status = fab_profile.project_status
    profile.purpose = fab_profile.purpose
    profile.references = get_projects_profile_references(fab_project=fab_project)
    return profile


# Keywords - Projects Profile
def get_projects_profile_keywords(fab_project: FabricProjects = None) -> [ProfilesKeywords]:
    keywords = ProfilesKeywords.query.filter(
        ProfilesKeywords.profile_id == fab_project.profile.id
    )
    response = []
    for k in keywords:
        kw = ProfilesKeywords()
        kw.keyword = k.keyword
        response.append(kw)
    return response


# Notebooks - Projects Profile
def get_projects_profile_notebooks(fab_project: FabricProjects = None) -> [object]:
    notebooks = []
    return notebooks


# References - Projects Profile
def get_projects_profile_references(fab_project: FabricProjects = None) -> [ProfileProjectsOneReferences]:
    references = ProfilesReferences.query.filter_by(profile_id=fab_project.profile.id)
    response = []
    for r in references:
        ref = ProfilesReferences()
        ref.description = r.description
        ref.url = r.url
        response.append(ref)
    return response


# Publications - Projects
def get_projects_publications(fab_project: FabricProjects = None) -> [object]:
    publications = []
    return publications


# Keywords - Project Profile
def get_projects_tags(fab_project: FabricProjects = None) -> [str]:
    tags = ProjectsTags.query.filter_by(projects_id=fab_project.id)
    response = []
    for t in tags:
        response.append(t.tag)
    return response


# Creators, Owners and Members - Projects
def get_projects_personnel(fab_project: FabricProjects = None, personnel_type: str = None) -> [People]:
    """
    * Denotes required fields
    - email: <string>
    - * name: <string>
    - * uuid: <string>
    """
    personnel = []
    if personnel_type == 'creators':
        personnel = fab_project.project_creators
    elif personnel_type == 'owners':
        personnel = fab_project.project_owners
    elif personnel_type == 'members':
        personnel = fab_project.project_members
    personnel_data = []
    for p in personnel:
        # get preferences (show_email)
        prefs = get_people_preferences(fab_person=FabricPeople.query.filter_by(uuid=p.uuid).one_or_none())
        # set person attributes
        person = People()
        person.email = p.preferred_email if prefs.__getattribute__('show_email') else None
        person.name = p.display_name
        person.uuid = p.uuid
        # add person to personnel_data
        personnel_data.append(person)

    return personnel_data


# Memberships - Projects
def get_projects_memberships(fab_project: FabricProjects = None) -> ProjectMemberships:
    response = ProjectMemberships()

    return response


# Projects
def get_projects(search: str = None, offset: int = 0,
                 limit: int = int(os.getenv('CORE_API_DEFAULT_LIMIT'))) -> InlineResponse2003:
    """
    Return all for public projects (private depends on membership of user)
    - "created": "string",
    - "description": "string",
    - "facility": "string",
    - "is_public": true,
    - "memberships": {
        "project_creator": false,
        "project_member": false,
        "project_owner": false
      },
    - "name": "string",
    - "uuid": "string"
    """
    # set page to retrieve
    _page = int((offset + limit) / limit)
    # get paginated search results
    if search:
        data_page = FabricProjects.query.filter(
            (FabricProjects.active.is_(True)) &
            (FabricProjects.name.ilike("%" + search + "%"))
        ).order_by(FabricProjects.name).paginate(page=_page, per_page=limit, error_out=False)
    else:
        data_page = FabricProjects.query.filter(
            FabricProjects.active.is_(True)
        ).order_by(FabricProjects.name).paginate(
            page=_page, per_page=limit, error_out=False)
    # set people data
    projects = InlineResponse2003()
    projects.data = []
    for item in data_page.items:
        # set project attributes
        project = Projects()
        project.created = str(item.created)
        project.description = item.description
        project.facility = item.facility
        # TODO set is_public attribute
        project.is_public = True
        # TODO set membership_type object
        project.memberships = get_projects_memberships()
        project.name = item.name
        project.uuid = item.uuid
        projects.data.append(project)
    # set links
    projects.links = Model200OkPaginatedLinks()
    _URL_OFFSET_LIMIT = '{0}offset={1}&limit={2}'
    base = '{0}/projects?'.format(_SERVER_URL) if not search else '{0}/projects?search={1}&'.format(_SERVER_URL, search)
    projects.links.first = _URL_OFFSET_LIMIT.format(base, 0, limit) if data_page.pages > 0 else None
    projects.links.last = _URL_OFFSET_LIMIT.format(base, int((data_page.pages - 1) * limit),
                                                   limit) if data_page.pages > 0 else None
    projects.links.next = _URL_OFFSET_LIMIT.format(base, int(offset + limit), limit) if data_page.has_next else None
    projects.links.prev = _URL_OFFSET_LIMIT.format(base, int(offset - limit), limit) if data_page.has_prev else None
    # set offset, limit and size
    projects.limit = limit
    projects.offset = offset
    projects.size = len(projects.data)

    return projects


def get_projects_one(fab_project: FabricProjects = None) -> InlineResponse2004:
    """
    * Denotes required fields
    - * active: <bool>
    - * created: <string>
    - * description: <string>
    - * facility: <string>
    - * is_public: <bool>
    - * memberships: {
        - project_creator: <booL>
        - project_member: <bool>
        - project_owner: <bool>
      }
    - * modified: <string>
    - * name: <string>
    - profile: {
        - award_information: <string>
        - goals: <string>
        - keywords: []
        - notebooks: []
        - project_status: <string>
        - purpose: <string>
        - references: []
      }
    - * project_creators: []
    - project_members: []
    - project_owners: []
    - publications: []
    - * tags: []
    - * uuid: <string>
    """
    # required attributes
    project = ProjectsOne()
    project.active = fab_project.active
    project.created = str(fab_project.created)
    project.description = fab_project.description
    project.facility = fab_project.facility
    # TODO get memberships from user making request
    project.memberships = get_projects_memberships(fab_project=fab_project)
    project.modified = str(fab_project.modified)
    project.name = fab_project.name
    project.project_creators = get_projects_personnel(fab_project=fab_project, personnel_type='creators')
    project.tags = get_projects_tags(fab_project=fab_project)
    project.uuid = fab_project.uuid

    # optional attributes by preference
    prefs = get_projects_preferences(fab_project=fab_project)
    # TODO get is_public from preferences
    project.is_public = prefs.__getattribute__('is_public')
    project.profile = get_profile_projects_one(
        fab_project=fab_project) if prefs.__getattribute__('show_profile') else None
    project.project_owners = get_projects_personnel(
        fab_project=fab_project, personnel_type='owners') if prefs.__getattribute__('show_project_owners') else None
    project.project_members = get_projects_personnel(
        fab_project=fab_project, personnel_type='members') if prefs.__getattribute__('show_project_members') else None
    project.publications = get_projects_publications(
        fab_project=fab_project) if prefs.__getattribute__('show_publications') else None

    # project_one object
    project_one = InlineResponse2004()
    project_one.data = []
    project_one.data.append(project)

    return project_one


def get_projects_self(fab_project: FabricProjects = None) -> InlineResponse2005:
    """
    All fields are required
    - active: <bool>
    - created: <string>
    - description: <string>
    - facility: <string>
    - is_public: <bool>
    - memberships: {
        - project_creator: <booL>
        - project_member: <bool>
        - project_owner: <bool>
      }
    - modified: <string>
    - name: <string>
    - preferences: {
        - is_public: <bool>
        - show_profile: <bool>
        - show_project_members: <bool>
        - show_project_owners: <bool>
        - show_publications: <bool>
      }
    - profile: {
        - award_information: <string>
        - goals: <string>
        - keywords: []
        - notebooks: []
        - preferences: {
            - show_award_information: <bool>,
            - show_goals: <bool>
            - show_keywords: <bool>
            - show_notebooks: <bool>
            - show_project_status: <bool>
            - show_purpose: <bool>
            - show_references: <bool>
          }
        - project_status: <string>
        - purpose: <string>
        - references: []
      }
    - project_creators: []
    - project_members: []
    - project_owners: []
    - publications: []
    - tags: []
    - uuid: <string>
    """
    # required attributes
    project = ProjectsSelf()
    project.active = fab_project.active
    project.created = str(fab_project.created)
    project.description = fab_project.description
    project.facility = fab_project.facility
    # TODO get is_public from preferences
    prefs = get_projects_preferences(fab_project=fab_project)
    project.is_public = prefs.__getattribute__('is_public')
    # TODO get memberships from user making request
    project.memberships = get_projects_memberships(fab_project=fab_project)
    project.modified = str(fab_project.modified)
    project.name = fab_project.name
    project.preferences = prefs
    project.profile = get_profile_projects_self(fab_project=fab_project)
    project.project_creators = get_projects_personnel(fab_project=fab_project, personnel_type='creators')
    project.project_members = get_projects_personnel(fab_project=fab_project, personnel_type='members')
    project.project_owners = get_projects_personnel(fab_project=fab_project, personnel_type='owners')
    project.publications = get_projects_publications(fab_project=fab_project)
    project.tags = get_projects_tags(fab_project=fab_project)
    project.uuid = fab_project.uuid

    # project_self object
    project_self = InlineResponse2005()
    project_self.data = []
    project_self.data.append(project)

    return project_self

# Constants # Preferences Project Preferences - default = True     - is_public: <booL>     - show_profile: <booL>     - show_project_members: <booL>     - show_project_owners: <booL>     - show_publications: <booL> Profile People Preferences - default = True     - show_award_information: <booL>     - show_goals: <booL>     - show_keywords: <booL>     - show_notebooks: <booL>     - show_project_status: <booL>     - show_purpose: <booL>     - show_references: <bool> # Profiles All fields are optional (preference based)     - award_information: <string>     - goals: <string>     - keywords: []     - notebooks: []     - project_status: <string>     - purpose: <string>     - references: [] All fields are optional (preference based)     - award_information: <string>     - goals: <string>     - keywords: []     - notebooks: []     - project_status: <string>     - purpose: <string>     - references: [] # Keywords - Projects Profile # Notebooks - Projects Profile # References - Projects Profile # Publications - Projects # Keywords - Project Profile # Creators, Owners and Members - Projects * Denotes required fields     - email: <string>     - * name: <string>     - * uuid: <string> # get preferences (show_email) # set person attributes # add person to personnel_data # Memberships - Projects # Projects Return all for public projects (private depends on membership of user)     - "created": "string",     - "description": "string",     - "facility": "string",     - "is_public": true,     - "memberships": {         "project_creator": false,         "project_member": false,         "project_owner": false       },     - "name": "string",     - "uuid": "string" # set page to retrieve # get paginated search results # set people data # set project attributes # TODO set is_public attribute # TODO set membership_type object # set links # set offset, limit and size * Denotes required fields     - * active: <bool>     - * created: <string>     - * description: <string>     - * facility: <string>     - * is_public: <bool>     - * memberships: {         - project_creator: <booL>         - project_member: <bool>         - project_owner: <bool>       }     - * modified: <string>     - * name: <string>     - profile: {         - award_information: <string>         - goals: <string>         - keywords: []         - notebooks: []         - project_status: <string>         - purpose: <string>         - references: []       }     - * project_creators: []     - project_members: []     - project_owners: []     - publications: []     - * tags: []     - * uuid: <string> # required attributes # TODO get memberships from user making request # optional attributes by preference # TODO get is_public from preferences # project_one object All fields are required     - active: <bool>     - created: <string>     - description: <string>     - facility: <string>     - is_public: <bool>     - memberships: {         - project_creator: <booL>         - project_member: <bool>         - project_owner: <bool>       }     - modified: <string>     - name: <string>     - preferences: {         - is_public: <bool>         - show_profile: <bool>         - show_project_members: <bool>         - show_project_owners: <bool>         - show_publications: <bool>       }     - profile: {         - award_information: <string>         - goals: <string>         - keywords: []         - notebooks: []         - preferences: {             - show_award_information: <bool>,             - show_goals: <bool>             - show_keywords: <bool>             - show_notebooks: <bool>             - show_project_status: <bool>             - show_purpose: <bool>             - show_references: <bool>           }         - project_status: <string>         - purpose: <string>         - references: []       }     - project_creators: []     - project_members: []     - project_owners: []     - publications: []     - tags: []     - uuid: <string> # required attributes # TODO get is_public from preferences # TODO get memberships from user making request # project_self object