angular.module('odoo')

    .factory('odooFactory', function (xmlrpc, methodCallManager) {
        return {
            auth: function (config, success, error) {
                xmlrpc.callMethod(methodCallManager.call('authenticate', config), [config.database, config.username, config.password, {}]).then(function (response) {
                    if (!response || response['faultCode']) {
                        return error(response);
                    }

                    success(response);
                }, function (xmlrpcError) {
                    error(xmlrpcError);
                });
            },
            read: function (model, domain, config, success, error) {
                xmlrpc.callMethod(methodCallManager.call('execute_kw', config), [config.database, config.id, config.password, model, 'search_read', [domain]]).then(function (response) {
                    if (!response || response['faultCode']) {
                        return error(response);
                    }

                    success(response);
                }, function (xmlrpcError) {
                    error(xmlrpcError);
                });
            },
            create: function (model, data, config, success, error) {
                xmlrpc.callMethod(methodCallManager.call('execute_kw', config), [config.database, config.id, config.password, model, 'create', [data]]).then(function (response) {
                    if (!response || response['faultCode']) {
                        return error(response);
                    }

                    success(response);
                }, function (xmlrpcError) {
                    error(xmlrpcError);
                });
            },
            write: function (model, id, data, config, success, error) {
                xmlrpc.callMethod(methodCallManager.call('execute_kw', config), [config.database, config.id, config.password, model, 'write', [[id], data]]).then(function (response) {
                    if (!response || response['faultCode']) {
                        return error(response);
                    }

                    success(response);
                }, function (xmlrpcError) {
                    error(xmlrpcError);
                });
            },
            unlink: function (model, id, config, success, error) {
                xmlrpc.callMethod(methodCallManager.call('execute_kw', config), [config.database, config.id, config.password, model, 'unlink', [[id]]]).then(function (response) {
                    if (!response || response['faultCode']) {
                        return error(response);
                    }

                    success(response);
                }, function (xmlrpcError) {
                    error(xmlrpcError);
                });
            },
            check: function (model, operation, success, error) {
                xmlrpc.callMethod(methodCallManager.call('execute_kw', config), [config.database, config.id, config.password, model, 'check_access_rights', [operation], { 'raise_exception': false }]).then(function (response) {
                    if (!response || response['faultCode']) {
                        return error(response);
                    }

                    success(response);
                }, function (xmlrpcError) {
                    error(xmlrpcError);
                });
            },
            fields: function (model, config, success, error) {
                xmlrpc.callMethod(methodCallManager.call('execute_kw', config), [config.database, config.id, config.password, model, 'fields_get', [], { 'attributes': ['type', 'readonly', 'required', 'relation', 'relation_field'] }]).then(function (response) {
                    if (!response || response['faultCode']) {
                        return error(response);
                    }

                    success(response);
                }, function (xmlrpcError) {
                    error(xmlrpcError);
                });
            }
        }
    })

    .factory('methodCallManager', function (xmlrpc) {
        return {
            call: function (methodName, configuration) {
                var hostName = configuration.host + ':' + configuration.port;

                if (!hostName.startsWith('http://')) {
                    hostName = 'http://' + hostName;
                }

                if (methodName == 'authenticate') {
                    xmlrpc.config({ hostName: hostName, pathName: '/xmlrpc/2/common' });
                } else {
                    xmlrpc.config({ hostName: hostName, pathName: '/xmlrpc/2/object' });
                }

                return methodName;
            }
        }
    });
