#
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
#
# BitBake Toaster Implementation
#
# Copyright (C) 2015        Intel Corporation
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

from toastergui.widgets import ToasterTable
from orm.models import Recipe, ProjectLayer, Layer_Version, Machine, Project
from orm.models import CustomImageRecipe, Package, Target, Build, LogMessage, Task
from orm.models import CustomImagePackage
from django.db.models import Q, Max, Sum, Count, When, Case, Value, IntegerField
from django.conf.urls import url
from django.core.urlresolvers import reverse, resolve
from django.http import HttpResponse
from django.views.generic import TemplateView

from toastergui.tablefilter import TableFilter
from toastergui.tablefilter import TableFilterActionToggle
from toastergui.tablefilter import TableFilterActionDateRange
from toastergui.tablefilter import TableFilterActionDay

class ProjectFilters(object):
    @staticmethod
    def in_project(project_layers):
        return Q(layer_version__in=project_layers)

    @staticmethod
    def not_in_project(project_layers):
        return ~(ProjectFilters.in_project(project_layers))

class LayersTable(ToasterTable):
    """Table of layers in Toaster"""

    def __init__(self, *args, **kwargs):
        super(LayersTable, self).__init__(*args, **kwargs)
        self.default_orderby = "layer__name"
        self.title = "Compatible layers"

    def get_context_data(self, **kwargs):
        context = super(LayersTable, self).get_context_data(**kwargs)

        project = Project.objects.get(pk=kwargs['pid'])
        context['project'] = project

        return context

    def setup_filters(self, *args, **kwargs):
        project = Project.objects.get(pk=kwargs['pid'])
        self.project_layers = ProjectLayer.objects.filter(project=project)

        in_current_project_filter = TableFilter(
            "in_current_project",
            "Filter by project layers"
        )

        criteria = Q(projectlayer__in=self.project_layers)

        in_project_action = TableFilterActionToggle(
            "in_project",
            "Layers added to this project",
            criteria
        )

        not_in_project_action = TableFilterActionToggle(
            "not_in_project",
            "Layers not added to this project",
            ~criteria
        )

        in_current_project_filter.add_action(in_project_action)
        in_current_project_filter.add_action(not_in_project_action)
        self.add_filter(in_current_project_filter)

    def setup_queryset(self, *args, **kwargs):
        prj = Project.objects.get(pk = kwargs['pid'])
        compatible_layers = prj.get_all_compatible_layer_versions()

        self.static_context_extra['current_layers'] = \
                prj.get_project_layer_versions(pk=True)

        self.queryset = compatible_layers.order_by(self.default_orderby)

    def setup_columns(self, *args, **kwargs):

        layer_link_template = '''
        <a href="{% url 'layerdetails' extra.pid data.id %}">
          {{data.layer.name}}
        </a>
        '''

        self.add_column(title="Layer",
                        hideable=False,
                        orderable=True,
                        static_data_name="layer__name",
                        static_data_template=layer_link_template)

        self.add_column(title="Summary",
                        field_name="layer__summary")

        git_url_template = '''
        <a href="{% url 'layerdetails' extra.pid data.id %}">
          <code>{{data.layer.vcs_url}}</code>
        </a>
        {% if data.get_vcs_link_url %}
        <a target="_blank" href="{{ data.get_vcs_link_url }}">
           <i class="icon-share get-info"></i>
        </a>
        {% endif %}
        '''

        self.add_column(title="Git repository URL",
                        help_text="The Git repository for the layer source code",
                        hidden=True,
                        static_data_name="layer__vcs_url",
                        static_data_template=git_url_template)

        git_dir_template = '''
        <a href="{% url 'layerdetails' extra.pid data.id %}">
         <code>{{data.dirpath}}</code>
        </a>
        {% if data.dirpath and data.get_vcs_dirpath_link_url %}
        <a target="_blank" href="{{ data.get_vcs_dirpath_link_url }}">
          <i class="icon-share get-info"></i>
        </a>
        {% endif %}'''

        self.add_column(title="Subdirectory",
                        help_text="The layer directory within the Git repository",
                        hidden=True,
                        static_data_name="git_subdir",
                        static_data_template=git_dir_template)

        revision_template =  '''
        {% load projecttags  %}
        {% with vcs_ref=data.get_vcs_reference %}
        {% if vcs_ref|is_shaid %}
        <a class="btn" data-content="<ul class='unstyled'> <li>{{vcs_ref}}</li> </ul>">
        {{vcs_ref|truncatechars:10}}
        </a>
        {% else %}
        {{vcs_ref}}
        {% endif %}
        {% endwith %}
        '''

        self.add_column(title="Git revision",
                        help_text="The Git branch, tag or commit. For the layers from the OpenEmbedded layer source, the revision is always the branch compatible with the Yocto Project version you selected for this project",
                        static_data_name="revision",
                        static_data_template=revision_template)

        deps_template = '''
        {% with ods=data.dependencies.all%}
        {% if ods.count %}
            <a class="btn" title="<a href='{% url "layerdetails" extra.pid data.id %}'>{{data.layer.name}}</a> dependencies"
        data-content="<ul class='unstyled'>
        {% for i in ods%}
        <li><a href='{% url "layerdetails" extra.pid i.depends_on.pk %}'>{{i.depends_on.layer.name}}</a></li>
        {% endfor %}
        </ul>">
        {{ods.count}}
        </a>
        {% endif %}
        {% endwith %}
        '''

        self.add_column(title="Dependencies",
                        help_text="Other layers a layer depends upon",
                        static_data_name="dependencies",
                        static_data_template=deps_template)

        self.add_column(title="Add | Remove",
                        help_text="Add or remove layers to / from your project",
                        hideable=False,
                        filter_name="in_current_project",
                        static_data_name="add-del-layers",
                        static_data_template='{% include "layer_btn.html" %}')

        project = Project.objects.get(pk=kwargs['pid'])
        self.add_column(title="LayerDetailsUrl",
                        displayable = False,
                        field_name="layerdetailurl",
                        computation = lambda x: reverse('layerdetails', args=(project.id, x.id)))

        self.add_column(title="name",
                        displayable = False,
                        field_name="name",
                        computation = lambda x: x.layer.name)


class MachinesTable(ToasterTable):
    """Table of Machines in Toaster"""

    def __init__(self, *args, **kwargs):
        super(MachinesTable, self).__init__(*args, **kwargs)
        self.empty_state = "No machines maybe you need to do a build?"
        self.title = "Compatible machines"
        self.default_orderby = "name"

    def get_context_data(self, **kwargs):
        context = super(MachinesTable, self).get_context_data(**kwargs)
        context['project'] = Project.objects.get(pk=kwargs['pid'])
        return context

    def setup_filters(self, *args, **kwargs):
        project = Project.objects.get(pk=kwargs['pid'])

        in_current_project_filter = TableFilter(
            "in_current_project",
            "Filter by project machines"
        )

        in_project_action = TableFilterActionToggle(
            "in_project",
            "Machines provided by layers added to this project",
            ProjectFilters.in_project(self.project_layers)
        )

        not_in_project_action = TableFilterActionToggle(
            "not_in_project",
            "Machines provided by layers not added to this project",
            ProjectFilters.not_in_project(self.project_layers)
        )

        in_current_project_filter.add_action(in_project_action)
        in_current_project_filter.add_action(not_in_project_action)
        self.add_filter(in_current_project_filter)

    def setup_queryset(self, *args, **kwargs):
        prj = Project.objects.get(pk = kwargs['pid'])
        self.queryset = prj.get_all_compatible_machines()
        self.queryset = self.queryset.order_by(self.default_orderby)

        self.static_context_extra['current_layers'] = \
                self.project_layers = \
                prj.get_project_layer_versions(pk=True)

    def setup_columns(self, *args, **kwargs):

        self.add_column(title="Machine",
                        hideable=False,
                        orderable=True,
                        field_name="name")

        self.add_column(title="Description",
                        field_name="description")

        layer_link_template = '''
        <a href="{% url 'layerdetails' extra.pid data.layer_version.id %}">
        {{data.layer_version.layer.name}}</a>
        '''

        self.add_column(title="Layer",
                        static_data_name="layer_version__layer__name",
                        static_data_template=layer_link_template,
                        orderable=True)

        self.add_column(title="Git revision",
                        help_text="The Git branch, tag or commit. For the layers from the OpenEmbedded layer source, the revision is always the branch compatible with the Yocto Project version you selected for this project",
                        hidden=True,
                        field_name="layer_version__get_vcs_reference")

        machine_file_template = '''<code>conf/machine/{{data.name}}.conf</code>
        <a href="{{data.get_vcs_machine_file_link_url}}" target="_blank"><i class="icon-share get-info"></i></a>'''

        self.add_column(title="Machine file",
                        hidden=True,
                        static_data_name="machinefile",
                        static_data_template=machine_file_template)

        self.add_column(title="Select",
                        help_text="Sets the selected machine as the project machine. You can only have one machine per project",
                        hideable=False,
                        filter_name="in_current_project",
                        static_data_name="add-del-layers",
                        static_data_template='{% include "machine_btn.html" %}')


class LayerMachinesTable(MachinesTable):
    """ Smaller version of the Machines table for use in layer details """

    def __init__(self, *args, **kwargs):
        super(LayerMachinesTable, self).__init__(*args, **kwargs)

    def get_context_data(self, **kwargs):
        context = super(LayerMachinesTable, self).get_context_data(**kwargs)
        context['layerversion'] = Layer_Version.objects.get(pk=kwargs['layerid'])
        return context


    def setup_queryset(self, *args, **kwargs):
        MachinesTable.setup_queryset(self, *args, **kwargs)

        self.queryset = self.queryset.filter(layer_version__pk=int(kwargs['layerid']))
        self.queryset = self.queryset.order_by(self.default_orderby)
        self.static_context_extra['in_prj'] = ProjectLayer.objects.filter(Q(project=kwargs['pid']) & Q(layercommit=kwargs['layerid'])).count()

    def setup_columns(self, *args, **kwargs):
        self.add_column(title="Machine",
                        hideable=False,
                        orderable=True,
                        field_name="name")

        self.add_column(title="Description",
                        field_name="description")

        select_btn_template = '<a href="{% url "project" extra.pid %}?setMachine={{data.name}}" class="btn btn-block select-machine-btn" {% if extra.in_prj == 0%}disabled="disabled"{%endif%}>Select machine</a>'

        self.add_column(title="Select machine",
                        static_data_name="add-del-layers",
                        static_data_template=select_btn_template)


class RecipesTable(ToasterTable):
    """Table of All Recipes in Toaster"""

    def __init__(self, *args, **kwargs):
        super(RecipesTable, self).__init__(*args, **kwargs)
        self.empty_state = "Toaster has no recipe information. To generate recipe information you can configure a layer source then run a build."

    build_col = { 'title' : "Build",
            'help_text' : "Add or delete recipes to and from your project",
            'hideable' : False,
            'filter_name' : "in_current_project",
            'static_data_name' : "add-del-layers",
            'static_data_template' : '{% include "recipe_btn.html" %}'}

    def get_context_data(self, **kwargs):
        project = Project.objects.get(pk=kwargs['pid'])
        context = super(RecipesTable, self).get_context_data(**kwargs)

        context['project'] = project

        context['projectlayers'] = map(lambda prjlayer: prjlayer.layercommit.id, ProjectLayer.objects.filter(project=context['project']))

        return context

    def setup_filters(self, *args, **kwargs):
        table_filter = TableFilter(
            'in_current_project',
            'Filter by project recipes'
        )

        in_project_action = TableFilterActionToggle(
            'in_project',
            'Recipes provided by layers added to this project',
            ProjectFilters.in_project(self.project_layers)
        )

        not_in_project_action = TableFilterActionToggle(
            'not_in_project',
            'Recipes provided by layers not added to this project',
            ProjectFilters.not_in_project(self.project_layers)
        )

        table_filter.add_action(in_project_action)
        table_filter.add_action(not_in_project_action)
        self.add_filter(table_filter)

    def setup_queryset(self, *args, **kwargs):
        prj = Project.objects.get(pk = kwargs['pid'])

        # Project layers used by the filters
        self.project_layers = prj.get_project_layer_versions(pk=True)

        # Project layers used to switch the button states
        self.static_context_extra['current_layers'] = self.project_layers

        self.queryset = prj.get_all_compatible_recipes()


    def setup_columns(self, *args, **kwargs):

        self.add_column(title="Version",
                        hidden=False,
                        field_name="version")

        self.add_column(title="Description",
                        field_name="get_description_or_summary")

        recipe_file_template = '''
        <code>{{data.file_path}}</code>
        <a href="{{data.get_vcs_recipe_file_link_url}}" target="_blank">
          <i class="icon-share get-info"></i>
        </a>
         '''

        self.add_column(title="Recipe file",
                        help_text="Path to the recipe .bb file",
                        hidden=True,
                        static_data_name="recipe-file",
                        static_data_template=recipe_file_template)

        self.add_column(title="Section",
                        help_text="The section in which recipes should be categorized",
                        hidden=True,
                        orderable=True,
                        field_name="section")

        layer_link_template = '''
        <a href="{% url 'layerdetails' extra.pid data.layer_version.id %}">
        {{data.layer_version.layer.name}}</a>
        '''

        self.add_column(title="Layer",
                        help_text="The name of the layer providing the recipe",
                        orderable=True,
                        static_data_name="layer_version__layer__name",
                        static_data_template=layer_link_template)

        self.add_column(title="License",
                        help_text="The list of source licenses for the recipe. Multiple license names separated by the pipe character indicates a choice between licenses. Multiple license names separated by the ampersand character indicates multiple licenses exist that cover different parts of the source",
                        hidden=True,
                        orderable=True,
                        field_name="license")

        self.add_column(title="Git revision",
                        hidden=True,
                        field_name="layer_version__get_vcs_reference")


class LayerRecipesTable(RecipesTable):
    """ Smaller version of the Recipes table for use in layer details """

    def __init__(self, *args, **kwargs):
        super(LayerRecipesTable, self).__init__(*args, **kwargs)
        self.default_orderby = "name"

    def get_context_data(self, **kwargs):
        context = super(LayerRecipesTable, self).get_context_data(**kwargs)
        context['layerversion'] = Layer_Version.objects.get(pk=kwargs['layerid'])
        return context


    def setup_queryset(self, *args, **kwargs):
        self.queryset = \
                Recipe.objects.filter(layer_version__pk=int(kwargs['layerid']))

        self.queryset = self.queryset.order_by(self.default_orderby)
        self.static_context_extra['in_prj'] = ProjectLayer.objects.filter(Q(project=kwargs['pid']) & Q(layercommit=kwargs['layerid'])).count()

    def setup_columns(self, *args, **kwargs):
        self.add_column(title="Recipe",
                        help_text="Information about a single piece of software, including where to download the source, configuration options, how to compile the source files and how to package the compiled output",
                        hideable=False,
                        orderable=True,
                        field_name="name")

        self.add_column(title="Version",
                        field_name="version")

        self.add_column(title="Description",
                        field_name="get_description_or_summary")

        build_recipe_template ='<button class="btn btn-block build-recipe-btn" data-recipe-name="{{data.name}}" {%if extra.in_prj == 0 %}disabled="disabled"{%endif%}>Build recipe</button>'

        self.add_column(title="Build recipe",
                        static_data_name="add-del-layers",
                        static_data_template=build_recipe_template)

class CustomImagesTable(ToasterTable):
    """ Table to display your custom images """
    def __init__(self, *args, **kwargs):
        super(CustomImagesTable, self).__init__(*args, **kwargs)
        self.title = "Custom images"
        self.default_orderby = "name"

    def get_context_data(self, **kwargs):
        context = super(CustomImagesTable, self).get_context_data(**kwargs)
        project = Project.objects.get(pk=kwargs['pid'])
        # TODO put project into the ToasterTable base class
        context['project'] = project
        return context

    def setup_queryset(self, *args, **kwargs):
        prj = Project.objects.get(pk = kwargs['pid'])
        self.queryset = CustomImageRecipe.objects.filter(project=prj)
        self.queryset = self.queryset.order_by(self.default_orderby)

    def setup_columns(self, *args, **kwargs):

        name_link_template = '''
        <a href="{% url 'customrecipe' extra.pid data.id %}">
          {{data.name}}
        </a>
        '''

        self.add_column(title="Custom image",
                        hideable=False,
                        orderable=True,
                        field_name="name",
                        static_data_name="name",
                        static_data_template=name_link_template)

        recipe_file_template = '''
        <code>{{data.name}}_{{data.version}}.bb</code>
        <a href="{% url 'customrecipedownload' extra.pid data.pk %}">
        <i class="icon-download-alt" data-original-title="Download recipe
        file"></i>
        </a>'''

        self.add_column(title="Recipe file",
                        static_data_name='recipe_file_download',
                        static_data_template=recipe_file_template)

        approx_packages_template = '''
        <a href="{% url 'customrecipe' extra.pid data.id %}">
          {{data.get_all_packages.count}}
        </a>'''

        self.add_column(title="Approx packages",
                        static_data_name='approx_packages',
                        static_data_template=approx_packages_template)


        build_btn_template = '''
        <button data-recipe-name="{{data.name}}"
        class="btn btn-block build-recipe-btn" style="margin-top: 5px;" >
        Build
        </button>'''

        self.add_column(title="Build",
                        hideable=False,
                        static_data_name='build_custom_img',
                        static_data_template=build_btn_template)

class ImageRecipesTable(RecipesTable):
    """ A subset of the recipes table which displayed just image recipes """

    def __init__(self, *args, **kwargs):
        super(ImageRecipesTable, self).__init__(*args, **kwargs)
        self.title = "Compatible image recipes"
        self.default_orderby = "name"

    def setup_queryset(self, *args, **kwargs):
        super(ImageRecipesTable, self).setup_queryset(*args, **kwargs)

        custom_image_recipes = CustomImageRecipe.objects.filter(
                project=kwargs['pid'])
        self.queryset = self.queryset.filter(
                Q(is_image=True) & ~Q(pk__in=custom_image_recipes))
        self.queryset = self.queryset.order_by(self.default_orderby)


    def setup_columns(self, *args, **kwargs):

        name_link_template = '''
        <a href="{% url 'recipedetails' extra.pid data.pk %}">{{data.name}}</a>
        '''

        self.add_column(title="Image recipe",
                        help_text="When you build an image recipe, you get an "
                                  "image: a root file system you can"
                                  "deploy to a machine",
                        hideable=False,
                        orderable=True,
                        static_data_name="name",
                        static_data_template=name_link_template,
                        field_name="name")

        super(ImageRecipesTable, self).setup_columns(*args, **kwargs)

        self.add_column(**RecipesTable.build_col)


class NewCustomImagesTable(ImageRecipesTable):
    """ Table which displays Images recipes which can be customised """
    def __init__(self, *args, **kwargs):
        super(NewCustomImagesTable, self).__init__(*args, **kwargs)
        self.title = "Select the image recipe you want to customise"

    def setup_queryset(self, *args, **kwargs):
        super(ImageRecipesTable, self).setup_queryset(*args, **kwargs)
        prj = Project.objects.get(pk = kwargs['pid'])
        self.static_context_extra['current_layers'] = \
                prj.get_project_layer_versions(pk=True)

        self.queryset = self.queryset.filter(is_image=True)

    def setup_columns(self, *args, **kwargs):

        name_link_template = '''
        <a href="{% url 'recipedetails' extra.pid data.pk %}">{{data.name}}</a>
        '''

        self.add_column(title="Image recipe",
                        help_text="When you build an image recipe, you get an "
                                  "image: a root file system you can"
                                  "deploy to a machine",
                        hideable=False,
                        orderable=True,
                        static_data_name="name",
                        static_data_template=name_link_template,
                        field_name="name")

        super(ImageRecipesTable, self).setup_columns(*args, **kwargs)

        self.add_column(title="Customise",
                        hideable=False,
                        filter_name="in_current_project",
                        static_data_name="customise-or-add-recipe",
                        static_data_template='{% include "customise_btn.html" %}')


class SoftwareRecipesTable(RecipesTable):
    """ Displays just the software recipes """
    def __init__(self, *args, **kwargs):
        super(SoftwareRecipesTable, self).__init__(*args, **kwargs)
        self.title = "Compatible software recipes"
        self.default_orderby = "name"

    def setup_queryset(self, *args, **kwargs):
        super(SoftwareRecipesTable, self).setup_queryset(*args, **kwargs)

        self.queryset = self.queryset.filter(is_image=False)
        self.queryset = self.queryset.order_by(self.default_orderby)


    def setup_columns(self, *args, **kwargs):
        self.add_column(title="Software recipe",
                        help_text="Information about a single piece of "
                        "software, including where to download the source, "
                        "configuration options, how to compile the source "
                        "files and how to package the compiled output",
                        hideable=False,
                        orderable=True,
                        field_name="name")

        super(SoftwareRecipesTable, self).setup_columns(*args, **kwargs)

        self.add_column(**RecipesTable.build_col)

class PackagesTable(ToasterTable):
    """ Table to display the packages in a recipe from it's last successful
    build"""

    def __init__(self, *args, **kwargs):
        super(PackagesTable, self).__init__(*args, **kwargs)
        self.title = "Packages included"
        self.packages = None
        self.default_orderby = "name"

    def create_package_list(self, recipe, project_id):
        """Creates a list of packages for the specified recipe by looking for
        the last SUCCEEDED build of ther recipe"""

        target = Target.objects.filter(Q(target=recipe.name) &
                                       Q(build__project_id=project_id) &
                                       Q(build__outcome=Build.SUCCEEDED)
                                      ).last()

        if target:
            pkgs = target.target_installed_package_set.values_list('package',
                                                                   flat=True)
            return Package.objects.filter(pk__in=pkgs)

        # Target/recipe never successfully built so empty queryset
        return Package.objects.none()

    def get_context_data(self, **kwargs):
        """Context for rendering the sidebar and other items on the recipe
        details page """
        context = super(PackagesTable, self).get_context_data(**kwargs)

        recipe = Recipe.objects.get(pk=kwargs['recipe_id'])
        project = Project.objects.get(pk=kwargs['pid'])

        in_project = (recipe.layer_version.pk in
                      project.get_project_layer_versions(pk=True))

        packages = self.create_package_list(recipe, project.pk)

        context.update({'project': project,
                        'recipe' : recipe,
                        'packages': packages,
                        'approx_pkg_size' : packages.aggregate(Sum('size')),
                        'in_project' : in_project,
                       })

        return context

    def setup_queryset(self, *args, **kwargs):
        recipe = Recipe.objects.get(pk=kwargs['recipe_id'])

        self.queryset = self.create_package_list(recipe, kwargs['pid'])
        self.queryset = self.queryset.order_by('name')

    def setup_columns(self, *args, **kwargs):
        self.add_column(title="Package",
                        hideable=False,
                        orderable=True,
                        field_name="name")

        self.add_column(title="Package Version",
                        field_name="version",
                        hideable=False)

        self.add_column(title="Approx Size",
                        orderable=True,
                        static_data_name="size",
                        static_data_template="{% load projecttags %} \
                        {{data.size|filtered_filesizeformat}}")

        self.add_column(title="License",
                        field_name="license",
                        orderable=True)


        self.add_column(title="Dependencies",
                        static_data_name="dependencies",
                        static_data_template='\
                        {% include "snippets/pkg_dependencies_popover.html" %}')

        self.add_column(title="Reverse dependencies",
                        static_data_name="reverse_dependencies",
                        static_data_template='\
                        {% include "snippets/pkg_revdependencies_popover.html" %}',
                        hidden=True)

        self.add_column(title="Recipe",
                        field_name="recipe__name",
                        orderable=True,
                        hidden=True)

        self.add_column(title="Recipe version",
                        field_name="recipe__version",
                        hidden=True)


class SelectPackagesTable(PackagesTable):
    """ Table to display the packages to add and remove from an image """

    def __init__(self, *args, **kwargs):
        super(SelectPackagesTable, self).__init__(*args, **kwargs)
        self.title = "Add | Remove packages"

    def setup_queryset(self, *args, **kwargs):
        self.cust_recipe =\
            CustomImageRecipe.objects.get(pk=kwargs['custrecipeid'])
        prj = Project.objects.get(pk = kwargs['pid'])

        current_packages = self.cust_recipe.get_all_packages()

        current_recipes = prj.get_available_recipes()

        # only show packages where recipes->layers are in the project
        self.queryset = CustomImagePackage.objects.filter(
                ~Q(recipe=None) &
                Q(recipe__in=current_recipes))

        self.queryset = self.queryset.order_by('name')

        self.static_context_extra['recipe_id'] = kwargs['custrecipeid']
        self.static_context_extra['current_packages'] = \
                current_packages.values_list('pk', flat=True)

    def get_context_data(self, **kwargs):
        # to reuse the Super class map the custrecipeid to the recipe_id
        kwargs['recipe_id'] = kwargs['custrecipeid']
        context = super(SelectPackagesTable, self).get_context_data(**kwargs)
        custom_recipe = \
            CustomImageRecipe.objects.get(pk=kwargs['custrecipeid'])

        context['recipe'] = custom_recipe
        context['approx_pkg_size'] = \
                        custom_recipe.get_all_packages().aggregate(Sum('size'))
        return context


    def setup_columns(self, *args, **kwargs):
        super(SelectPackagesTable, self).setup_columns(*args, **kwargs)

        add_remove_template = '{% include "pkg_add_rm_btn.html" %}'

        self.add_column(title="Add | Remove",
                        hideable=False,
                        help_text="Use the add and remove buttons to modify "
                        "the package content of your custom image",
                        static_data_name="add_rm_pkg_btn",
                        static_data_template=add_remove_template,
                        filter_name='in_current_image_filter')

    def setup_filters(self, *args, **kwargs):
        in_current_image_filter = TableFilter(
            'in_current_image_filter',
            'Filter by added packages'
        )

        in_image_action = TableFilterActionToggle(
            'in_image',
            'Packages in %s' % self.cust_recipe.name,
            Q(pk__in=self.static_context_extra['current_packages'])
        )

        not_in_image_action = TableFilterActionToggle(
            'not_in_image',
            'Packages not added to %s' % self.cust_recipe.name,
            ~Q(pk__in=self.static_context_extra['current_packages'])
        )

        in_current_image_filter.add_action(in_image_action)
        in_current_image_filter.add_action(not_in_image_action)
        self.add_filter(in_current_image_filter)

class ProjectsTable(ToasterTable):
    """Table of projects in Toaster"""

    def __init__(self, *args, **kwargs):
        super(ProjectsTable, self).__init__(*args, **kwargs)
        self.default_orderby = '-updated'
        self.title = 'All projects'
        self.static_context_extra['Build'] = Build

    def get_context_data(self, **kwargs):
        return super(ProjectsTable, self).get_context_data(**kwargs)

    def setup_queryset(self, *args, **kwargs):
        queryset = Project.objects.all()

        # annotate each project with its number of builds
        queryset = queryset.annotate(num_builds=Count('build'))

        # exclude the command line builds project if it has no builds
        q_default_with_builds = Q(is_default=True) & Q(num_builds__gt=0)
        queryset = queryset.filter(Q(is_default=False) |
                                   q_default_with_builds)

        # order rows
        queryset = queryset.order_by(self.default_orderby)

        self.queryset = queryset

    # columns: last activity on (updated) - DEFAULT, project (name), release,
    # machine, number of builds, last build outcome, recipe (name),  errors,
    # warnings, image files
    def setup_columns(self, *args, **kwargs):
        name_template = '''
        {% load project_url_tag %}
        <span data-project-field="name">
          <a href="{% project_url data %}">
            {{data.name}}
          </a>
        </span>
        '''

        last_activity_on_template = '''
        {% load project_url_tag %}
        <span data-project-field="updated">
          <a href="{% project_url data %}">
            {{data.updated | date:"d/m/y H:i"}}
          </a>
        </span>
        '''

        release_template = '''
        <span data-project-field="release">
          {% if data.release %}
            <a href="{% url 'project' data.id %}#project-details">
                {{data.release.name}}
            </a>
          {% elif data.is_default %}
            <span class="muted">Not applicable</span>
            <i class="icon-question-sign get-help hover-help"
               data-original-title="This project does not have a release set.
               It simply collects information about the builds you start from
               the command line while Toaster is running"
               style="visibility: hidden;">
            </i>
          {% else %}
            No release available
          {% endif %}
        </span>
        '''

        machine_template = '''
        <span data-project-field="machine">
          {% if data.is_default %}
            <span class="muted">Not applicable</span>
            <i class="icon-question-sign get-help hover-help"
               data-original-title="This project does not have a machine
               set. It simply collects information about the builds you
               start from the command line while Toaster is running"
               style="visibility: hidden;"></i>
          {% else %}
            <a href="{% url 'project' data.id %}#machine-distro">
              {{data.get_current_machine_name}}
            </a>
          {% endif %}
        </span>
        '''

        number_of_builds_template = '''
        {% if data.get_number_of_builds > 0 %}
          <a href="{% url 'projectbuilds' data.id %}">
            {{data.get_number_of_builds}}
          </a>
        {% else %}
          <span class="muted">0</span>
        {% endif %}
        '''

        last_build_outcome_template = '''
        {% if data.get_number_of_builds > 0 %}
          <a href="{% url 'builddashboard' data.get_last_build_id %}">
            {% if data.get_last_outcome == extra.Build.SUCCEEDED %}
              <i class="icon-ok-sign success"></i>
            {% elif data.get_last_outcome == extra.Build.FAILED %}
              <i class="icon-minus-sign error"></i>
            {% endif %}
          </a>
        {% endif %}
        '''

        recipe_template = '''
        {% if data.get_number_of_builds > 0 %}
          <a href="{% url "builddashboard" data.get_last_build_id %}">
            {{data.get_last_target}}
          </a>
        {% endif %}
        '''

        errors_template = '''
        {% if data.get_number_of_builds > 0 and data.get_last_errors > 0 %}
          <a class="errors.count error"
             href="{% url "builddashboard" data.get_last_build_id %}#errors">
            {{data.get_last_errors}} error{{data.get_last_errors | pluralize}}
          </a>
        {% endif %}
        '''

        warnings_template = '''
        {% if data.get_number_of_builds > 0 and data.get_last_warnings > 0 %}
          <a class="warnings.count warning"
             href="{% url "builddashboard" data.get_last_build_id %}#warnings">
            {{data.get_last_warnings}} warning{{data.get_last_warnings | pluralize}}
          </a>
        {% endif %}
        '''

        image_files_template = '''
        {% if data.get_number_of_builds > 0 and data.get_last_outcome == extra.Build.SUCCEEDED %}
          <a href="{% url "builddashboard" data.get_last_build_id %}#images">
            {{data.get_last_build_extensions}}
          </a>
        {% endif %}
        '''

        self.add_column(title='Project',
                        hideable=False,
                        orderable=True,
                        static_data_name='name',
                        static_data_template=name_template)

        self.add_column(title='Last activity on',
                        help_text='Starting date and time of the \
                                   last project build. If the project has no \
                                   builds, this shows the date the project was \
                                   created.',
                        hideable=False,
                        orderable=True,
                        static_data_name='updated',
                        static_data_template=last_activity_on_template)

        self.add_column(title='Release',
                        help_text='The version of the build system used by \
                                   the project',
                        hideable=False,
                        orderable=True,
                        static_data_name='release',
                        static_data_template=release_template)

        self.add_column(title='Machine',
                        help_text='The hardware currently selected for the \
                                   project',
                        hideable=False,
                        orderable=False,
                        static_data_name='machine',
                        static_data_template=machine_template)

        self.add_column(title='Number of builds',
                        help_text='The number of builds which have been run \
                                   for the project',
                        hideable=False,
                        orderable=False,
                        static_data_name='number_of_builds',
                        static_data_template=number_of_builds_template)

        self.add_column(title='Last build outcome',
                        help_text='Indicates whether the last project build \
                                   completed successfully or failed',
                        hideable=True,
                        orderable=False,
                        static_data_name='last_build_outcome',
                        static_data_template=last_build_outcome_template)

        self.add_column(title='Recipe',
                        help_text='The last recipe which was built in this \
                                   project',
                        hideable=True,
                        orderable=False,
                        static_data_name='recipe_name',
                        static_data_template=recipe_template)

        self.add_column(title='Errors',
                        help_text='The number of errors encountered during \
                                   the last project build (if any)',
                        hideable=True,
                        orderable=False,
                        static_data_name='errors',
                        static_data_template=errors_template)

        self.add_column(title='Warnings',
                        help_text='The number of warnings encountered during \
                                   the last project build (if any)',
                        hideable=True,
                        hidden=True,
                        orderable=False,
                        static_data_name='warnings',
                        static_data_template=warnings_template)

        self.add_column(title='Image files',
                        help_text='The root file system types produced by \
                                   the last project build',
                        hideable=True,
                        hidden=True,
                        orderable=False,
                        static_data_name='image_files',
                        static_data_template=image_files_template)

class BuildsTable(ToasterTable):
    """Table of builds in Toaster"""

    def __init__(self, *args, **kwargs):
        super(BuildsTable, self).__init__(*args, **kwargs)
        self.default_orderby = '-completed_on'
        self.static_context_extra['Build'] = Build
        self.static_context_extra['Task'] = Task

        # attributes that are overridden in subclasses

        # title for the page
        self.title = ''

        # 'project' or 'all'; determines how the mrb (most recent builds)
        # section is displayed
        self.mrb_type = ''

    def get_builds(self):
        """
        overridden in ProjectBuildsTable to return builds for a
        single project
        """
        return Build.objects.all()

    def get_context_data(self, **kwargs):
        context = super(BuildsTable, self).get_context_data(**kwargs)

        # should be set in subclasses
        context['mru'] = []

        context['mrb_type'] = self.mrb_type

        return context

    def setup_queryset(self, *args, **kwargs):
        """
        The queryset is annotated so that it can be sorted by number of
        errors and number of warnings; but note that the criteria for
        finding the log messages to populate these fields should match those
        used in the Build model (orm/models.py) to populate the errors and
        warnings properties
        """
        queryset = self.get_builds()

        # Don't include in progress builds pr cancelled builds
        queryset = queryset.exclude(Q(outcome=Build.IN_PROGRESS) |
                                    Q(outcome=Build.CANCELLED))

        # sort
        queryset = queryset.order_by(self.default_orderby)

        # annotate with number of ERROR, EXCEPTION and CRITICAL log messages
        criteria = (Q(logmessage__level=LogMessage.ERROR) |
                    Q(logmessage__level=LogMessage.EXCEPTION) |
                    Q(logmessage__level=LogMessage.CRITICAL))

        queryset = queryset.annotate(
            errors_no=Count(
                Case(
                    When(criteria, then=Value(1)),
                    output_field=IntegerField()
                )
            )
        )

        # annotate with number of WARNING log messages
        queryset = queryset.annotate(
            warnings_no=Count(
                Case(
                    When(logmessage__level=LogMessage.WARNING, then=Value(1)),
                    output_field=IntegerField()
                )
            )
        )

        self.queryset = queryset

    def setup_columns(self, *args, **kwargs):
        outcome_template = '''
        <a href="{% url "builddashboard" data.id %}">
            {% if data.outcome == data.SUCCEEDED %}
                <i class="icon-ok-sign success"></i>
            {% elif data.outcome == data.FAILED %}
                <i class="icon-minus-sign error"></i>
            {% endif %}
        </a>

        {% if data.cooker_log_path %}
            &nbsp;
            <a href="{% url "build_artifact" data.id "cookerlog" data.id %}">
               <i class="icon-download-alt get-help"
               data-original-title="Download build log"></i>
            </a>
        {% endif %}
        '''

        recipe_template = '''
        {% for target_label in data.target_labels %}
            <a href="{% url "builddashboard" data.id %}">
                {{target_label}}
            </a>
            <br />
        {% endfor %}
        '''

        machine_template = '''
        <a href="{% url "builddashboard" data.id %}">
            {{data.machine}}
        </a>
        '''

        started_on_template = '''
        <a href="{% url "builddashboard" data.id %}">
            {{data.started_on | date:"d/m/y H:i"}}
        </a>
        '''

        completed_on_template = '''
        <a href="{% url "builddashboard" data.id %}">
            {{data.completed_on | date:"d/m/y H:i"}}
        </a>
        '''

        failed_tasks_template = '''
        {% if data.failed_tasks.count == 1 %}
            <a href="{% url "task" data.id data.failed_tasks.0.id %}">
                <span class="error">
                    {{data.failed_tasks.0.recipe.name}}.{{data.failed_tasks.0.task_name}}
                </span>
            </a>
            <a href="{% url "build_artifact" data.id "tasklogfile" data.failed_tasks.0.id %}">
                <i class="icon-download-alt"
                   data-original-title="Download task log file">
                </i>
            </a>
        {% elif data.failed_tasks.count > 1 %}
            <a href="{% url "tasks" data.id %}?filter=outcome%3A{{extra.Task.OUTCOME_FAILED}}">
                <span class="error">{{data.failed_tasks.count}} tasks</span>
            </a>
        {% endif %}
        '''

        errors_template = '''
        {% if data.errors_no %}
            <a class="errors.count error" href="{% url "builddashboard" data.id %}#errors">
                {{data.errors_no}} error{{data.errors_no|pluralize}}
            </a>
        {% endif %}
        '''

        warnings_template = '''
        {% if data.warnings_no %}
            <a class="warnings.count warning" href="{% url "builddashboard" data.id %}#warnings">
                {{data.warnings_no}} warning{{data.warnings_no|pluralize}}
            </a>
        {% endif %}
        '''

        time_template = '''
        {% load projecttags %}
        <a href="{% url "buildtime" data.id %}">
            {{data.timespent_seconds | sectohms}}
        </a>
        '''

        image_files_template = '''
        {% if data.outcome == extra.Build.SUCCEEDED %}
          <a href="{% url "builddashboard" data.id %}#images">
            {{data.get_image_file_extensions}}
          </a>
        {% endif %}
        '''

        self.add_column(title='Outcome',
                        help_text='Final state of the build (successful \
                                   or failed)',
                        hideable=False,
                        orderable=True,
                        filter_name='outcome_filter',
                        static_data_name='outcome',
                        static_data_template=outcome_template)

        self.add_column(title='Recipe',
                        help_text='What was built (i.e. one or more recipes \
                                   or image recipes)',
                        hideable=False,
                        orderable=False,
                        static_data_name='target',
                        static_data_template=recipe_template)

        self.add_column(title='Machine',
                        help_text='Hardware for which you are building a \
                                   recipe or image recipe',
                        hideable=False,
                        orderable=True,
                        static_data_name='machine',
                        static_data_template=machine_template)

        self.add_column(title='Started on',
                        help_text='The date and time when the build started',
                        hideable=True,
                        hidden=True,
                        orderable=True,
                        filter_name='started_on_filter',
                        static_data_name='started_on',
                        static_data_template=started_on_template)

        self.add_column(title='Completed on',
                        help_text='The date and time when the build finished',
                        hideable=False,
                        orderable=True,
                        filter_name='completed_on_filter',
                        static_data_name='completed_on',
                        static_data_template=completed_on_template)

        self.add_column(title='Failed tasks',
                        help_text='The number of tasks which failed during \
                                   the build',
                        hideable=True,
                        orderable=False,
                        filter_name='failed_tasks_filter',
                        static_data_name='failed_tasks',
                        static_data_template=failed_tasks_template)

        self.add_column(title='Errors',
                        help_text='The number of errors encountered during \
                                   the build (if any)',
                        hideable=True,
                        orderable=True,
                        static_data_name='errors_no',
                        static_data_template=errors_template)

        self.add_column(title='Warnings',
                        help_text='The number of warnings encountered during \
                                   the build (if any)',
                        hideable=True,
                        orderable=True,
                        static_data_name='warnings_no',
                        static_data_template=warnings_template)

        self.add_column(title='Time',
                        help_text='How long the build took to finish',
                        hideable=True,
                        hidden=True,
                        orderable=False,
                        static_data_name='time',
                        static_data_template=time_template)

        self.add_column(title='Image files',
                        help_text='The root file system types produced by \
                                   the build',
                        hideable=True,
                        orderable=False,
                        static_data_name='image_files',
                        static_data_template=image_files_template)

    def setup_filters(self, *args, **kwargs):
        # outcomes
        outcome_filter = TableFilter(
            'outcome_filter',
            'Filter builds by outcome'
        )

        successful_builds_action = TableFilterActionToggle(
            'successful_builds',
            'Successful builds',
            Q(outcome=Build.SUCCEEDED)
        )

        failed_builds_action = TableFilterActionToggle(
            'failed_builds',
            'Failed builds',
            Q(outcome=Build.FAILED)
        )

        outcome_filter.add_action(successful_builds_action)
        outcome_filter.add_action(failed_builds_action)
        self.add_filter(outcome_filter)

        # started on
        started_on_filter = TableFilter(
            'started_on_filter',
            'Filter by date when build was started'
        )

        started_today_action = TableFilterActionDay(
            'today',
            'Today\'s builds',
            'started_on',
            'today'
        )

        started_yesterday_action = TableFilterActionDay(
            'yesterday',
            'Yesterday\'s builds',
            'started_on',
            'yesterday'
        )

        by_started_date_range_action = TableFilterActionDateRange(
            'date_range',
            'Build date range',
            'started_on'
        )

        started_on_filter.add_action(started_today_action)
        started_on_filter.add_action(started_yesterday_action)
        started_on_filter.add_action(by_started_date_range_action)
        self.add_filter(started_on_filter)

        # completed on
        completed_on_filter = TableFilter(
            'completed_on_filter',
            'Filter by date when build was completed'
        )

        completed_today_action = TableFilterActionDay(
            'today',
            'Today\'s builds',
            'completed_on',
            'today'
        )

        completed_yesterday_action = TableFilterActionDay(
            'yesterday',
            'Yesterday\'s builds',
            'completed_on',
            'yesterday'
        )

        by_completed_date_range_action = TableFilterActionDateRange(
            'date_range',
            'Build date range',
            'completed_on'
        )

        completed_on_filter.add_action(completed_today_action)
        completed_on_filter.add_action(completed_yesterday_action)
        completed_on_filter.add_action(by_completed_date_range_action)
        self.add_filter(completed_on_filter)

        # failed tasks
        failed_tasks_filter = TableFilter(
            'failed_tasks_filter',
            'Filter builds by failed tasks'
        )

        criteria = Q(task_build__outcome=Task.OUTCOME_FAILED)

        with_failed_tasks_action = TableFilterActionToggle(
            'with_failed_tasks',
            'Builds with failed tasks',
            criteria
        )

        without_failed_tasks_action = TableFilterActionToggle(
            'without_failed_tasks',
            'Builds without failed tasks',
            ~criteria
        )

        failed_tasks_filter.add_action(with_failed_tasks_action)
        failed_tasks_filter.add_action(without_failed_tasks_action)
        self.add_filter(failed_tasks_filter)


class AllBuildsTable(BuildsTable):
    """ Builds page for all builds """

    def __init__(self, *args, **kwargs):
        super(AllBuildsTable, self).__init__(*args, **kwargs)
        self.title = 'All builds'
        self.mrb_type = 'all'

    def setup_columns(self, *args, **kwargs):
        """
        All builds page shows a column for the project
        """

        super(AllBuildsTable, self).setup_columns(*args, **kwargs)

        project_template = '''
        {% load project_url_tag %}
        <a href="{% project_url data.project %}">
            {{data.project.name}}
        </a>
        {% if data.project.is_default %}
            <i class="icon-question-sign get-help hover-help" title=""
               data-original-title="This project shows information about
               the builds you start from the command line while Toaster is
               running" style="visibility: hidden;"></i>
        {% endif %}
        '''

        self.add_column(title='Project',
                        hideable=True,
                        orderable=True,
                        static_data_name='project',
                        static_data_template=project_template)

    def get_context_data(self, **kwargs):
        """ Get all builds for the recent builds area """
        context = super(AllBuildsTable, self).get_context_data(**kwargs)
        context['mru'] = Build.get_recent()
        return context

class ProjectBuildsTable(BuildsTable):
    """
    Builds page for a single project; a BuildsTable, with the queryset
    filtered by project
    """

    def __init__(self, *args, **kwargs):
        super(ProjectBuildsTable, self).__init__(*args, **kwargs)
        self.title = 'All project builds'
        self.mrb_type = 'project'

        # set from the querystring
        self.project_id = None

    def setup_columns(self, *args, **kwargs):
        """
        Project builds table doesn't show the machines column by default
        """

        super(ProjectBuildsTable, self).setup_columns(*args, **kwargs)

        # hide the machine column
        self.set_column_hidden('Machine', True)

        # allow the machine column to be hidden by the user
        self.set_column_hideable('Machine', True)

    def setup_queryset(self, *args, **kwargs):
        """
        NOTE: self.project_id must be set before calling super(),
        as it's used in setup_queryset()
        """
        self.project_id = kwargs['pid']
        super(ProjectBuildsTable, self).setup_queryset(*args, **kwargs)

        project = Project.objects.get(pk=self.project_id)
        self.queryset = self.queryset.filter(project=project)

    def get_context_data(self, **kwargs):
        """
        Get recent builds for this project, and the project itself

        NOTE: self.project_id must be set before calling super(),
        as it's used in get_context_data()
        """
        self.project_id = kwargs['pid']
        context = super(ProjectBuildsTable, self).get_context_data(**kwargs)

        project = Project.objects.get(pk=self.project_id)
        context['mru'] = Build.get_recent(project)
        context['project'] = project

        return context
