text: # Copyright 2010 Google Inc. All Rights Reserved.
  #
  # 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.
  
  """BITE Project model.
  
  Bite Project model is used to differ projects, which is created by
  a lead.
  """
  
  __author__ = ('phu@google.com (Po Hu)'
                'jasonstredwick@google.com (Jason Stredwick)')
  
  import json
  
  from google.appengine.ext import db
  from models import model_helper
  
  
  class Error(Exception):
    pass
  
  
  class MissingProjectNameError(Error):
    """Missing the project name."""
  
  
  class DuplicatedProjectNameError(Error):
    """Has the project name existing."""
  
  
  class NoProjectFoundError(Error):
    """A project with the given name was not found."""
  
  
  class BiteProject(db.Model):
    """Contains project related info."""
    # General information
    name = db.StringProperty(required=False, default='')
    description = db.TextProperty(required=False, default='')
    emails = db.StringListProperty(default=[])
  
    # Creation Information
    visible = db.BooleanProperty(required=False, default=True)
    created_by = db.UserProperty(required=False, auto_current_user_add=True)
    created_time = db.DateTimeProperty(required=False, auto_now_add=True)
    last_modified_time = db.DateTimeProperty(required=False, auto_now=True)
    last_modified_by = db.UserProperty(required=False, auto_current_user=True)
  
    # External affiliations
    provider = db.StringProperty(required=False)
    provider_info = db.StringProperty(required=False, default='')
  
    # Run settings
    worker_mode_token = db.StringProperty(required=False, default='')
    start_url_replacement = db.StringProperty(required=False, default='')
    line_timeout_limit = db.IntegerProperty(required=False, default=15)
    max_runs_per_test = db.IntegerProperty(required=False, default=5)
    test_case_line_length = db.IntegerProperty(required=False, default=80)
    save_screen_shot = db.BooleanProperty(required=False, default=True)
  
  
  def _LookupProject(name):
    """Retrieve a project database entry."""
    if not name:
      raise MissingProjectNameError('There is no project name defined.')
  
    project = BiteProject.get_by_key_name(name)
    if not project:
      raise NoProjectFoundError(''.join(['Project (', name, ') not found.']))
  
    return project
  
  
  def AddProject(name, data):
    """Adds a project."""
    if not name:
      raise MissingProjectNameError('There is no project name defined.')
  
    if BiteProject.get_by_key_name(name):
      raise DuplicatedProjectNameError('Duplicated project name error.')
  
    # Assume name is ascii.
    project = BiteProject.get_or_insert(key_name=str(name), name=name)
    if data:
      data_obj = json.loads(data)
      model_helper.Update(project, data_obj, exclude=['name'])
      project.put()
  
    return project
  
  
  def GetAllProjects():
    """Returns a list of all the BiteProject entities."""
    return BiteProject.all()
  
  
  def GetDefaultProject():
    """Return a project in the default state."""
    return BiteProject()
  
  
  def GetProject(name):
    """Get a project."""
    return _LookupProject(name)
  
  
  def ListProjects():
    """List all projects."""
    query = BiteProject.all(keys_only=True)
    keys = [result.name() for result in query]
    return json.dumps(keys)
  
  
  def DeleteProject(name):
    """Delete a project."""
    _LookupProject(name).delete()
  
  
  def UpdateProject(name, data):
    """Update a project."""
    project = _LookupProject(name)
  
    if data:
      data_obj = json.loads(data)
      model_helper.Update(project, data_obj, exclude=['name'])
      project.put()
  
    return project
  
  