odoo.define('jd_base.system_log_access', function (require) {
    "use strict";
    var ActionManager = require('web.ActionManager');
    var core = require('web.core');
    var data = require('web.data');
    var data_manager = require('web.data_manager');
    var Model = require('web.DataModel')
    var pyeval = require('web.pyeval');

    ActionManager.include({
        /**
         * Execute an OpenERP action
         *
         * @param {Number|String|String|Object} Can be either an action id, an action XML id, a client action tag or an action descriptor.
         * @param {Object} [options]
         * @param {Boolean} [options.clear_breadcrumbs=false] Clear the breadcrumbs history list
         * @param {Boolean} [options.replace_breadcrumb=false] Replace the current breadcrumb with the action
         * @param {Function} [options.on_reverse_breadcrumb] Callback to be executed whenever an anterior breadcrumb item is clicked on.
         * @param {Function} [options.hide_breadcrumb] Do not display this widget's title in the breadcrumb
         * @param {Function} [options.on_close] Callback to be executed when the dialog is closed (only relevant for target=new actions)
         * @param {Function} [options.action_menu_id] Manually set the menu id on the fly.
         * @param {Object} [options.additional_context] Additional context to be merged with the action's context.
         * @return {jQuery.Deferred} Action loaded
         */
        do_action: function(action, options) {
            options = _.defaults(options || {}, {
                clear_breadcrumbs: false,
                replace_last_action: false,
                on_reverse_breadcrumb: function() {},
                hide_breadcrumb: false,
                on_close: function() {},
                action_menu_id: null,
                additional_context: {},
            });
            if (action === false) {
                action = { type: 'ir.actions.act_window_close' };
            } else if (_.isString(action) && core.action_registry.contains(action)) {
                var action_client = { type: "ir.actions.client", tag: action, params: {} };
                return this.do_action(action_client, options);
            } else if (_.isNumber(action) || _.isString(action)) {
                var self = this;
                var additional_context = {
                    active_id : options.additional_context.active_id,
                    active_ids : options.additional_context.active_ids,
                    active_model : options.additional_context.active_model
                };
                return data_manager.load_action(action, additional_context).then(function(result) {
                    return self.do_action(result, options);
                });
            }

            core.bus.trigger('action', action);

            // Force clear breadcrumbs if action's target is main
            options.clear_breadcrumbs = (action.target === 'main') || options.clear_breadcrumbs;

            // Ensure context & domain are evaluated and can be manipulated/used
            var ncontext = new data.CompoundContext(options.additional_context, action.context || {});
            action.context = pyeval.eval('context', ncontext);
            if (action.context.active_id || action.context.active_ids) {
                // Here we assume that when an `active_id` or `active_ids` is used
                // in the context, we are in a `related` action, so we disable the
                // searchview's default custom filters.
                action.context.search_disable_custom_filters = true;
            }
            if (action.domain) {
                action.domain = pyeval.eval(
                    'domain', action.domain, action.context || {});
            }

            if (!action.type) {
                console.error("No type for action", action);
                return $.Deferred().reject();
            }

            var type = action.type.replace(/\./g,'_');
            action.menu_id = options.action_menu_id;
            action.res_id = options.res_id || action.res_id;
            action.context.params = _.extend({ 'action' : action.id }, action.context.params);
            if (!(type in this)) {
                console.error("Action manager can't handle action of type " + action.type, action);
                return $.Deferred().reject();
            }

            // Special case for Dashboards, this should definitively be done upstream
            if (action.res_model === 'board.board' && action.view_mode === 'form') {
                action.target = 'inline';
                _.extend(action.flags, {
                    headless: true,
                    views_switcher: false,
                    display_title: false,
                    search_view: false,
                    pager: false,
                    sidebar: false,
                    action_buttons: false
                });
            } else {
                var popup = action.target === 'new';
                var inline = action.target === 'inline' || action.target === 'inlineview';
                var form = _.str.startsWith(action.view_mode, 'form');
                action.flags = _.defaults(action.flags || {}, {
                    views_switcher : !popup && !inline,
                    search_view : !(popup && form) && !inline,
                    action_buttons : !popup && !inline,
                    sidebar : !popup && !inline,
                    pager : (!popup || !form) && !inline,
                    display_title : !popup,
                    headless: (popup || inline) && form,
                    search_disable_custom_filters: action.context && action.context.search_disable_custom_filters,
                });
            }

            // create access log
            if (action.type == 'ir.actions.act_window' && action.id && action.res_model) {
                var action_id = action.id;
                var model_name = action.res_model;
                var log_model = new Model('jd.system.log.access');
                log_model.call('do_logging', [action_id, model_name]);
            }

            return $.when(this[type](action, options)).then(function() {
                return action;
            });
        },
    })
});