angular.module('odoo')

    /**
     *
     */
    .factory('odooFactory', function (
        $localStorage,
        xmlrpc,
        methodCallManager
    ) {
        var configuration = $localStorage;

        /**
         *
         */
        var auth = function (success, error) {
            xmlrpc.callMethod(methodCallManager.call('authenticate', configuration), [configuration.database, configuration.username, configuration.password, {}]).then(function (response) {
                if (!response || response['faultCode']) {
                    return error(response);
                }

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

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

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

        /**
         *
         */
        var create = function (model, data, success, error) {
            xmlrpc.callMethod(methodCallManager.call('execute_kw', configuration), [configuration.database, configuration.id, configuration.password, model, 'create', [data]]).then(function (response) {
                if (!response || response['faultCode']) {
                    return error(response);
                }

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

        /**
         *
         */
        var write = function (model, id, data, success, error) {
            xmlrpc.callMethod(methodCallManager.call('execute_kw', configuration), [configuration.database, configuration.id, configuration.password, model, 'write', [[id], data]]).then(function (response) {
                if (!response || response['faultCode']) {
                    return error(response);
                }

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

        /**
         *
         */
        var unlink = function (model, id, success, error) {
            xmlrpc.callMethod(methodCallManager.call('execute_kw', configuration), [configuration.database, configuration.id, configuration.password, model, 'unlink', [[id]]]).then(function (response) {
                if (!response || response['faultCode']) {
                    return error(response);
                }

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

        /**
         *
         */
        var check = function (model, operation, success, error) {
            xmlrpc.callMethod(methodCallManager.call('execute_kw', configuration), [configuration.database, configuration.id, configuration.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);
            });
        }

        /**
         *
         */
        var fields = function (model, success, error) {
            xmlrpc.callMethod(methodCallManager.call('execute_kw', configuration), [configuration.database, configuration.id, configuration.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);
            });
        }

        return {
            auth: auth,
            read: read,
            create: create,
            write: write,
            unlink: unlink,
            check: check,
            fields: fields
        }
    })

    /**
     *
     */
    .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;
            }
        }
    });
