'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _extends2 = require('babel-runtime/helpers/extends');

var _extends3 = _interopRequireDefault(_extends2);

var _omit = require('omit.js');

var _omit2 = _interopRequireDefault(_omit);

var _constantCRS = require('./constantCRS');

var _constantCRS2 = _interopRequireDefault(_constantCRS);

var _methodsUtil = require('../../_util/methods-util');

var _isPlainObject = require('lodash/isPlainObject');

var _isPlainObject2 = _interopRequireDefault(_isPlainObject);

var _providers = require('../providers');

var _services = require('../layers/services');

var _query = require('../query');

var _controls = require('../../map/controls');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

/**
 * 验证地图的proxyURL代理服务地址属性
 */
/**
 * @文件说明: 效验地图Map核心属性的有效性
 * @创建人: pjtools@vip.qq.com
 * @创建时间: 2020-03-17 22:34:39
 */

var validateProxyURL = function validateProxyURL(proxyURL) {
  if (!proxyURL) {
    console.error('地图Map的代理服务地址[proxyURL]属性未设定，可能导致请求服务时出现跨域等问题.');
    return '';
  }
  if (typeof proxyURL !== 'string' || !(0, _methodsUtil.isHttpUrl)((0, _methodsUtil.getUrlToLink)(proxyURL))) {
    console.error('地图Map的代理服务地址[proxyURL]属性不是一个有效的HTTP服务链接地址.');
    return '';
  }

  return proxyURL;
};

/**
 * 验证地图的units地图单位属性
 */
var validateMapUnits = function validateMapUnits(units) {
  if (units) {
    if (typeof units === 'string' && ['degrees', 'm'].indexOf(units) !== -1) {
      return units;
    }
    console.error('地图Map的单位[units]属性不是有效的值.');
  }
  return 'degrees';
};

/**
 * 验证地图的层级属性
 */
var validateMapZoom = function validateMapZoom(key, zoom, defaultValue) {
  if (!(0, _methodsUtil.isEmpty)(zoom)) {
    if (typeof zoom !== 'number' || zoom < 0 || zoom > 22) {
      console.error('\u5730\u56FEMap\u7684[' + key + ']\u5C42\u7EA7\u5C5E\u6027\u4E0D\u662F0-22\u4E4B\u95F4\u7684\u6709\u6548\u6570\u503C.');
      return defaultValue !== null && defaultValue !== undefined ? defaultValue : null;
    }
  }
  return zoom !== null && zoom !== undefined ? zoom : defaultValue;
};

/**
 * 验证地图的Bounds坐标范围属性
 */
var validateMapBounds = function validateMapBounds(key, bounds) {
  if (!(0, _methodsUtil.isEmpty)(bounds)) {
    if (!((0, _methodsUtil.isArray)(bounds) && bounds.length === 2 && (0, _methodsUtil.isCoordinate)(bounds[0]) && (0, _methodsUtil.isCoordinate)(bounds[1]))) {
      console.error('\u5730\u56FEMap\u7684[' + key + ']\u5730\u7406\u8303\u56F4\u5C5E\u6027\u4E0D\u662F\u6709\u6548[[minx,miny],[maxx,maxy]]\u683C\u5F0F\u5750\u6807.');
      return null;
    }
  }
  return bounds;
};

/**
 * 验证地图的倾斜属性
 */
var validateMapPitch = function validateMapPitch(key, pitch, defaultValue) {
  if (!(0, _methodsUtil.isEmpty)(pitch)) {
    if (typeof pitch !== 'number' || pitch < 0 || pitch > 60) {
      console.error('\u5730\u56FEMap\u7684[' + key + ']\u503E\u659C\u5C5E\u6027\u4E0D\u662F0-60\u4E4B\u95F4\u7684\u6709\u6548\u6570\u503C.');
      return defaultValue !== null && defaultValue !== undefined ? defaultValue : null;
    }
  }
  return pitch !== null && pitch !== undefined ? pitch : defaultValue;
};

/**
 * 验证地图的基础视图相关属性
 */
var validateBasicParams = function validateBasicParams(options) {
  // 验证地图的中心点
  if (options.center) {
    if (!(0, _methodsUtil.isCoordinate)(options.center)) {
      if (!((0, _methodsUtil.isArray)(options.center) && options.center.join(',') === '0,0')) {
        console.error('地图Map的中心点坐标[center]属性不是有效的值.');
      }
      options.center = [0, 0];
    }
  } else {
    options.center = [0, 0];
  }
  // 验证地图的层级
  options.zoom = validateMapZoom('zoom', options.zoom, 0);
  options.minZoom = validateMapZoom('minZoom', options.minZoom, 0);
  options.maxZoom = validateMapZoom('maxZoom', options.maxZoom, 22);
  if (options.minZoom > options.maxZoom) {
    console.error('地图Map的[minZoom]属性数值不能大于[maxZoom]属性数值.');
    options.minZoom = 0;
  }
  // 验证地图的BBOX范围坐标
  options.bounds = validateMapBounds('bounds', options.bounds);
  options.maxBounds = validateMapBounds('maxBounds', options.maxBounds);
  // 验证地图旋转度
  if (!(0, _methodsUtil.isEmpty)(options.bearing)) {
    if (typeof options.bearing !== 'number') {
      console.error('地图Map的旋转度[bearing]属性不是有效的数值.');
      options.bearing = 0;
    }
  } else {
    options.bearing = 0;
  }
  // 验证地图的倾斜度
  options.pitch = validateMapPitch('pitch', options.pitch, 0);
  options.minPitch = validateMapPitch('minPitch', options.minPitch, 0);
  options.maxPitch = validateMapPitch('maxPitch', options.maxPitch, 60);
  if (options.minPitch > options.maxPitch) {
    console.error('地图Map的[minPitch]属性数值不能大于[minPitch]属性数值.');
    options.minPitch = 0;
  }
  options.pitchWithRotate = (0, _methodsUtil.isBooleanFlase)(options.pitchWithRotate) ? false : true;
  // 验证地图单位
  options.units = validateMapUnits(options.units);

  return options;
};

/**
 * 验证地图的mapCRS地图投影属性
 */
var validateMapCRS = function validateMapCRS(mapCRS) {
  if (mapCRS) {
    if (typeof mapCRS === 'string') {
      // 判断是否为内置MapCRS投影名称
      if (_constantCRS2['default'][mapCRS]) {
        return _constantCRS2['default'][mapCRS];
      }
    } else if ((0, _isPlainObject2['default'])(mapCRS)) {
      var CRS = {};
      // 判断顶级金字塔是否为坐标数组
      if (mapCRS.topTileExtent && (0, _methodsUtil.isArray)(mapCRS.topTileExtent) && mapCRS.topTileExtent.length === 4 && (0, _methodsUtil.isNumeric)(mapCRS.topTileExtent[0]) && (0, _methodsUtil.isNumeric)(mapCRS.topTileExtent[1]) && (0, _methodsUtil.isNumeric)(mapCRS.topTileExtent[2]) && (0, _methodsUtil.isNumeric)(mapCRS.topTileExtent[3])) {
        CRS.topTileExtent = mapCRS.topTileExtent;
      }
      // 判断坐标转换系统
      if (!(0, _methodsUtil.isEmpty)(mapCRS.coordtransform)) {
        if (mapCRS.coordtransform !== 'none' && (0, _isPlainObject2['default'])(mapCRS.coordtransform) && (0, _methodsUtil.has)(mapCRS.coordtransform, 'toViewCoord') && (0, _methodsUtil.has)(mapCRS.coordtransform, 'fromViewCoord') && (0, _methodsUtil.isFunction)(mapCRS.coordtransform.toViewCoord) && (0, _methodsUtil.isFunction)(mapCRS.coordtransform.fromViewCoord)) {
          CRS.coordtransform = mapCRS.coordtransform;
        } else {
          CRS.coordtransform = 'none';
        }
      } else {
        CRS.coordtransform = 'none';
      }
      // 判断分辨率
      if (!(0, _methodsUtil.isEmpty)(mapCRS.resolutions) && (0, _methodsUtil.isArray)(mapCRS.resolutions)) {
        CRS.resolutions = mapCRS.resolutions;
      }
      // 判断瓦片尺寸
      if (!(0, _methodsUtil.isEmpty)(mapCRS.tileSize) && (0, _methodsUtil.isInteger)(mapCRS.tileSize)) {
        CRS.tileSize = mapCRS.tileSize;
      }
      // 判断是否有proj4属性
      if (!(0, _methodsUtil.isEmpty)(mapCRS.proj4)) {
        if ((0, _methodsUtil.isEmpty)(mapCRS.epsg)) {
          console.error('地图Map的投影[mapCRS]属性设定[proj4]属性时必须同时设定[epsg]属性.');
          return null;
        }
      }
      // 判断是否有必须属性
      if ((0, _methodsUtil.has)(CRS, 'topTileExtent') && (0, _methodsUtil.has)(CRS, 'coordtransform')) {
        CRS = (0, _extends3['default'])({}, CRS, (0, _omit2['default'])(mapCRS, ['topTileExtent', 'coordtransform', 'resolutions', 'tileSize']));
        return CRS;
      }
    }
    console.error('地图Map的投影[mapCRS]属性无法正确解析格式.');
  }
  return null;
};

/**
 * 验证地图的Service服务源对象的必填项是否符合规则
 * @param {Object} serviceItem 待检查的服务源对象
 * @param {String} prefixMsg 错误提示语的前缀信息文本
 */
var validateServiceLayerItem = function validateServiceLayerItem(serviceItem, prefixMsg) {
  // 验证自定义服务源的必须属性字段
  if (serviceItem.id && serviceItem.url && serviceItem.type) {
    if (!(0, _methodsUtil.isNumeric)(serviceItem.id) && typeof serviceItem.id !== 'string') {
      console.error(prefixMsg + '\u5C5E\u6027[id]\u683C\u5F0F\u6709\u8BEF.');
      return null;
    }
    if ((0, _methodsUtil.isArray)(serviceItem.url)) {
      for (var i = 0, len = serviceItem.url.length; i < len; i++) {
        if (typeof serviceItem.url[i] !== 'string' || !(0, _methodsUtil.isHttpUrl)(serviceItem.url[i])) {
          console.error(prefixMsg + '\u5C5E\u6027[url]\u683C\u5F0F\u6709\u8BEF.');
          return null;
        }
      }
    } else if (typeof serviceItem.url !== 'string' || !(0, _methodsUtil.isHttpUrl)(serviceItem.url)) {
      console.error(prefixMsg + '\u5C5E\u6027[url]\u683C\u5F0F\u6709\u8BEF.');
      return null;
    }
    if (_services.mapServicesTypeKeys.indexOf(serviceItem.type) === -1) {
      console.error(prefixMsg + '\u5C5E\u6027[type]\u4E0D\u5C5E\u4E8E\u5185\u7F6E\u7684\u670D\u52A1\u7C7B\u578B\u540D.');
      return null;
    }
    return serviceItem;
  } else {
    console.error(prefixMsg + '\u7F3A\u5C11\u5FC5\u586B\u9879[id]\u3001[url]\u3001[type]\u5C5E\u6027.');
    return null;
  }
};

/**
 * 验证地图的mapBasicLayers底图类型属性
 */
var validateMapBaseType = function validateMapBaseType(mapBaseType, mapBasicLayers) {
  var errorMsg = '地图Map的底图类型[mapBaseType]不属于底图服务源[mapBasicLayers]的Key名.';
  if (mapBasicLayers && (0, _isPlainObject2['default'])(mapBasicLayers) && typeof mapBaseType === 'string') {
    // 判断底图服务源是否为内置服务源
    if (mapBasicLayers.key && typeof mapBasicLayers.key === 'string') {
      var providersLayersKeys = _providers.providersLayersTypes[mapBasicLayers.key];
      if (providersLayersKeys.indexOf(mapBaseType) !== -1) {
        return mapBaseType;
      }
      console.error(errorMsg);
      return providersLayersKeys[0] || 'vec';
    } else {
      var basicLayersKeys = Object.keys(mapBasicLayers);
      if (basicLayersKeys.indexOf(mapBaseType) !== -1) {
        return mapBaseType;
      }
      console.error(errorMsg);
      return basicLayersKeys[0] || 'vec';
    }
  } else {
    console.error(errorMsg);
    return 'vec';
  }
};

/**
 * 验证地图的mapBaseType和mapBasicLayers地图基础底图属性
 */
var validateMapBasicLayers = function validateMapBasicLayers(options) {
  var errorNotProvidersMsg = '地图Map的基础底图[mapBasicLayers]不是内置设定的服务源Key名.';
  // 验证基础底图的服务源
  var mapBasicLayers = options.mapBasicLayers;
  var providersKeys = Object.keys(_providers.providersLayersTypes);
  // 判断底图服务源的值类型是否为字符串，则采用内置服务源验证模式
  if (typeof mapBasicLayers === 'string') {
    // 判断设定的Key是否为内置服务源的名称
    if (providersKeys.indexOf(mapBasicLayers) === -1) {
      console.error(errorNotProvidersMsg);
      options.mapBasicLayers = null;
    } else {
      // 转换成默认的Object对象
      options.mapBasicLayers = {
        key: mapBasicLayers,
        options: {}
      };
    }
  } else if ((0, _isPlainObject2['default'])(mapBasicLayers)) {
    // 判断是否为内置服务源的Object格式模式
    if (mapBasicLayers.key && typeof mapBasicLayers.key === 'string') {
      if (providersKeys.indexOf(mapBasicLayers.key) === -1) {
        console.error(errorNotProvidersMsg);
        options.mapBasicLayers = null;
      } else {
        // 补全错误的服务源的Options参数选项属性
        (!options.mapBasicLayers.options || !(0, _isPlainObject2['default'])(options.mapBasicLayers.options)) && (options.mapBasicLayers.options = {});
      }
    } else {
      var keys = Object.keys(mapBasicLayers);
      var basicLayers = {};
      keys.map(function (key) {
        if ((0, _methodsUtil.isArray)(mapBasicLayers[key])) {
          basicLayers[key] = [];
          mapBasicLayers[key].map(function (item, index) {
            // 验证自定义服务源的必须属性字段
            var serviceItem = validateServiceLayerItem(item, '\u5730\u56FEMap\u7684\u57FA\u7840\u5E95\u56FE[mapBasicLayers]\u81EA\u5B9A\u4E49[' + key + ']\u540D\u7684\u7D22\u5F15\'' + index + '\'\u670D\u52A1\u6E90\u5BF9\u8C61');
            serviceItem && basicLayers[key].push(serviceItem);
          });
        } else {
          console.error('\u5730\u56FEMap\u7684\u57FA\u7840\u5E95\u56FE[mapBasicLayers]\u81EA\u5B9A\u4E49\u683C\u5F0F\u7684[' + key + ']\u540D\u7684\u683C\u5F0F\u6709\u8BEF\uFF0C\u7C7B\u578B\u5FC5\u987B\u4E3A"Array"\u6570\u7EC4.');
        }
      });
      // 移除为空值的服务源对象
      var bLayers = {};
      Object.keys(basicLayers).map(function (key) {
        if (basicLayers[key] && (0, _methodsUtil.isArray)(basicLayers[key])) {
          bLayers[key] = basicLayers[key];
        }
      });
      options.mapBasicLayers = Object.keys(bLayers).length ? bLayers : null;
    }
  } else {
    console.error('地图Map的基础底图[mapBasicLayers]的格式有误，类型必须为"String"、"Object"其中的一种.');
    options.mapBasicLayers = null;
  }

  // 验证地图的mapBasicLayers底图类型
  options.mapBaseType = validateMapBaseType(options.mapBaseType, options.mapBasicLayers);

  return options;
};

/**
 * 验证地图的QueryService服务源对象的必填项是否符合规则
 * @param {Object} serviceItem 待检查的服务源对象
 * @param {String} prefixMsg 错误提示语的前缀信息文本
 */
var validateQueryServiceLayerItem = function validateQueryServiceLayerItem(serviceItem, prefixMsg) {
  // 验证自定义服务源的必须属性字段
  if (serviceItem.url && serviceItem.type && serviceItem.featureType) {
    if (typeof serviceItem.url !== 'string' || !(0, _methodsUtil.isHttpUrl)(serviceItem.url)) {
      console.error(prefixMsg + '\u5C5E\u6027[url]\u683C\u5F0F\u6709\u8BEF.');
      return null;
    }
    if (_query.mapQueryTypeKeys.indexOf(serviceItem.type) === -1) {
      console.error(prefixMsg + '\u5C5E\u6027[type]\u4E0D\u5C5E\u4E8E\u5185\u7F6E\u7684\u670D\u52A1\u7C7B\u578B\u540D.');
      return null;
    }
    if ((0, _methodsUtil.isEmpty)(serviceItem.featureType)) {
      console.error(prefixMsg + '\u5C5E\u6027[featureType]\u5FC5\u987B\u8BBE\u5B9A.');
      return null;
    }
    return serviceItem;
  } else {
    console.error(prefixMsg + '\u7F3A\u5C11\u5FC5\u586B\u9879[url]\u3001[type]\u3001[featureType]\u5C5E\u6027.');
    return null;
  }
};

/**
 * 验证地图的mapBaseType和mapBasicLayers地图基础底图属性
 */
var validateMapQueryServicesMapping = function validateMapQueryServicesMapping(options) {
  var queryServicesMapping = options.queryServicesMapping;
  if (queryServicesMapping && (0, _isPlainObject2['default'])(queryServicesMapping)) {
    var keys = Object.keys(queryServicesMapping);
    var mapping = {};
    keys.map(function (key) {
      if ((0, _isPlainObject2['default'])(queryServicesMapping[key])) {
        // 验证自定义服务源的必须属性字段
        var serviceItem = validateQueryServiceLayerItem(queryServicesMapping[key], '\u5730\u56FEMap\u7684\u67E5\u8BE2\u5206\u6790\u670D\u52A1\u6620\u5C04[queryServicesMapping]\u7684[' + key + ']\u670D\u52A1\u6E90\u5BF9\u8C61');
        serviceItem && (mapping[key] = serviceItem);
      } else {
        console.error('\u5730\u56FEMap\u7684\u67E5\u8BE2\u5206\u6790\u670D\u52A1\u6620\u5C04[queryServicesMapping]\u7684[' + key + ']\u540D\u7684\u683C\u5F0F\u6709\u8BEF\uFF0C\u7C7B\u578B\u5FC5\u987B\u4E3A"Object".');
      }
    });
    options.queryServicesMapping = mapping;
  } else {
    if (queryServicesMapping) {
      console.error('地图Map的查询分析服务映射[queryServicesMapping]必须为"Object"类型.');
    }
    options.queryServicesMapping = {};
  }

  return options;
};

/**
 * 验证地图的mapControls地图控件属性
 */
var validateMapControls = function validateMapControls(options) {
  var controls = [];
  if (options.mapControls) {
    if (!(0, _methodsUtil.isArray)(options.mapControls)) {
      console.error('地图Map的基础控件[mapControls]必须为“Array”类型.');
    } else if ((0, _methodsUtil.isNotEmptyArray)(options.mapControls)) {
      options.mapControls.map(function (item, index) {
        if (item.id && item.type) {
          if (_controls.mapControlsTypeKeys.indexOf(item.type) === -1) {
            console.error('\u5730\u56FEMap\u7684\u57FA\u7840\u63A7\u4EF6[mapControls]\u7684\u7D22\u5F15\'' + index + '\'\u63A7\u4EF6\u5C5E\u6027[type]\u4E0D\u5C5E\u4E8E\u5185\u7F6E\u63A7\u4EF6\u7C7B\u578B\u540D.');
            return;
          }
          if (item.position) {
            if (_controls.mapControlsPosition.indexOf(item.position) === -1) {
              console.error('\u5730\u56FEMap\u7684\u57FA\u7840\u63A7\u4EF6[mapControls]\u7684\u7D22\u5F15\'' + index + '\'\u63A7\u4EF6\u5C5E\u6027[position]\u503C\u4E0D\u5C5E\u4E8E[' + _controls.mapControlsPosition.join(', ') + ']\u5176\u4E2D\u4E00\u9879.');
              item.position = null;
            }
          }
          if (item.offset) {
            if (!(0, _methodsUtil.isNotEmptyArray)(item.offset) || item.offset.length !== 2) {
              console.error('\u5730\u56FEMap\u7684\u57FA\u7840\u63A7\u4EF6[mapControls]\u7684\u7D22\u5F15\'' + index + '\'\u63A7\u4EF6\u5C5E\u6027[offset]\u5FC5\u987B\u4E3A<number[x, y]>\u6570\u7EC4\u683C\u5F0F\u7C7B\u578B.');
              item.offset = [0, 0];
            }
          }
          !item.options && (item.options = {});
          controls.push(item);
        } else {
          console.error('\'\u5730\u56FEMap\u7684\u57FA\u7840\u63A7\u4EF6[mapControls]\u7684\u7D22\u5F15\'' + index + '\'\u7F3A\u5C11\u5FC5\u586B\u9879[id]\u3001[type]\u5C5E\u6027.');
        }
      });
    }
  }
  return options;
};

/**
 * 对地图Map的核心参数选项属性进行效验
 * @param {Object} options 待验证的地图Map参数选项
 */
var validate = function validate() {
  var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};

  // 验证地图的代理服务
  options.proxyURL = validateProxyURL(options.proxyURL);
  // 验证地图的基础视图属性
  options = validateBasicParams(options);
  // 验证地图的投影
  options.mapCRS = validateMapCRS(options.mapCRS);
  // 验证地图的基础底图属性结构
  options = validateMapBasicLayers(options);
  // 验证地图的控件属性结果
  options = validateMapControls(options);
  // 验证地图的查询分析服务映射的属性结构
  options = validateMapQueryServicesMapping(options);

  return options;
};

exports['default'] = validate;