/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import { cloneDeep, isEmpty, omit, pick, unset } from 'lodash';

import { convertToFormData } from '@/components/Upstream/service';
import { transformLabelValueToKeyValue } from '@/helpers';
import { HOST_REWRITE_TYPE, SCHEME_REWRITE, URI_REWRITE_TYPE } from '@/pages/Route/constants';

export const transformProxyRewrite2Plugin = (
  data: RouteModule.ProxyRewrite,
): RouteModule.ProxyRewrite => {
  const omitFieldsList: string[] = ['kvHeaders'];
  let headers: Record<string, string> = {};

  if (data.scheme !== 'http' && data.scheme !== 'https') {
    omitFieldsList.push('scheme');
  }

  if (data.method === '') {
    omitFieldsList.push('method');
  }

  (data.kvHeaders || []).forEach((kvHeader) => {
    if (kvHeader.key) {
      // support value to be an empty string, which means remove a header
      headers = {
        ...headers,
        [kvHeader.key]: kvHeader.value || '',
      };
    }
  });

  if (!isEmpty(headers)) {
    return omit(
      {
        ...data,
        headers,
      },
      omitFieldsList,
    );
  }

  return omit(data, omitFieldsList);
};

const transformProxyRewrite2Formdata = (pluginsData: any) => {
  const proxyRewriteData: RouteModule.ProxyRewrite = {
    scheme: SCHEME_REWRITE.KEEP,
  };
  let URIRewriteType = URI_REWRITE_TYPE.KEEP;
  let hostRewriteType = HOST_REWRITE_TYPE.KEEP;

  if (pluginsData) {
    if (pluginsData.regex_uri) {
      URIRewriteType = URI_REWRITE_TYPE.REGEXP;
    }

    if (pluginsData.uri && !pluginsData.regex_uri) {
      URIRewriteType = URI_REWRITE_TYPE.STATIC;
    }

    if (pluginsData.host) {
      hostRewriteType = HOST_REWRITE_TYPE.REWRITE;
    }

    Object.keys(pluginsData).forEach((key) => {
      switch (key) {
        case 'scheme':
          proxyRewriteData[key] =
            pluginsData[key] === SCHEME_REWRITE.HTTP || pluginsData[key] === SCHEME_REWRITE.HTTPS
              ? pluginsData[key]
              : SCHEME_REWRITE.KEEP;
          break;
        case 'uri':
        case 'regex_uri':
        case 'host':
        case 'method':
          proxyRewriteData[key] = pluginsData[key];
          break;
        case 'headers':
          Object.keys(pluginsData[key]).forEach((headerKey) => {
            proxyRewriteData.kvHeaders = [
              ...(proxyRewriteData.kvHeaders || []),
              {
                key: headerKey,
                value: pluginsData[key][headerKey],
              },
            ];
          });
          break;
        default:
          break;
      }
    });
  }

  return {
    proxyRewriteData,
    URIRewriteType,
    hostRewriteType,
  };
};

// Transform Route data then sent to API
export const transformStepData = ({
  form1Data,
  form2Data,
  advancedMatchingRules,
  step3Data,
}: RouteModule.RequestData) => {
  const { custom_normal_labels, custom_version_label, service_id = '' } = form1Data;

  let redirect: RouteModule.Redirect = {};
  const proxyRewriteFormData: RouteModule.ProxyRewrite = form1Data.proxyRewrite;
  const proxyRewriteConfig = transformProxyRewrite2Plugin(proxyRewriteFormData);

  const step3DataCloned = cloneDeep(step3Data);
  if (form1Data.redirectOption === 'disabled') {
    step3DataCloned.plugins = omit(step3Data.plugins, ['redirect']);
  } else if (form1Data.redirectOption === 'forceHttps') {
    redirect = { http_to_https: true };
  } else if (form1Data.redirectURI !== '') {
    redirect = {
      ret_code: form1Data.ret_code,
      uri: form1Data.redirectURI,
    };
  }

  const labels: Record<string, string> = {};
  transformLabelValueToKeyValue(custom_normal_labels).forEach(({ labelKey, labelValue }) => {
    labels[labelKey] = labelValue;
  });

  if (custom_version_label) {
    labels.API_VERSION = custom_version_label;
  }
  const data: Partial<RouteModule.Body> = {
    ...form1Data,
    labels,
    ...step3DataCloned,
    vars: advancedMatchingRules.map((rule) => {
      const { reverse, operator, position, name, value } = rule;
      let key: string;
      switch (position) {
        case 'cookie':
          key = `cookie_${name}`;
          break;
        case 'http':
          key = `http_${name}`;
          break;
        case 'arg':
          key = `arg_${name}`;
          break;
        case 'post_arg':
          key = `post_arg_${name}`;
          break;
        default:
          key = `${name}`;
      }
      let finalValue = value;
      if (operator === 'IN') {
        finalValue = JSON.parse(value as string);
      }
      return reverse ? [key, '!', operator, finalValue] : [key, operator, finalValue];
    }),
    // @ts-ignore
    methods: form1Data.methods.includes('ALL') ? [] : form1Data.methods,
    status: Number(form1Data.status),
  };

  if (!isEmpty(proxyRewriteConfig)) {
    if (Object.keys(data.plugins || {}).length === 0) {
      data.plugins = {};
    }
    data.plugins!['proxy-rewrite'] = proxyRewriteConfig;
  } else {
    unset(data.plugins, ['proxy-rewrite']);
  }

  if (data.uris && data.uris.filter(Boolean).length === 1) {
    [data.uri] = data.uris;
    delete data.uris;
  }
  if (data.hosts && data.hosts.filter(Boolean).length === 1) {
    [data.host] = data.hosts;
    delete data.hosts;
  }
  if (data.remote_addrs && data.remote_addrs.filter(Boolean).length === 1) {
    [data.remote_addr] = data.remote_addrs;
    delete data.remote_addrs;
  }

  if ((Object.keys(redirect).length === 0 || redirect.http_to_https) && form2Data) {
    /**
     * Due to convertToRequestData under the Upstream component,
     * if upstream_id === Custom or None, it will be omitted.
     * So upstream_id here mush be a valid Upstream ID from API.
     */
    if (form2Data.upstream_id) {
      data.upstream_id = form2Data.upstream_id;
    } else {
      data.upstream = form2Data;
    }

    if (redirect.http_to_https) {
      if (Object.keys(data.plugins || {}).length === 0) {
        data.plugins = {};
      }
      data.plugins!.redirect = redirect;
    }

    // Remove some of the frontend custom variables
    return omit(data, [
      'custom_version_label',
      'custom_normal_labels',
      'advancedMatchingRules',
      'upstreamHostList',
      'upstreamPath',
      'timeout',
      'redirectURI',
      'ret_code',
      'redirectOption',
      'URIRewriteType',
      'hostRewriteType',
      'proxyRewrite',
      service_id.length === 0 ? 'service_id' : '',
      !Object.keys(data.plugins || {}).length ? 'plugins' : '',
      !Object.keys(data.script || {}).length ? 'script' : '',
      form1Data.hosts?.filter(Boolean).length === 0 ? 'hosts' : '',
      form1Data.redirectOption === 'disabled' ? 'redirect' : '',
      data.remote_addrs?.filter(Boolean).length === 0 ? 'remote_addrs' : '',
      step3DataCloned.plugin_config_id === '' ? 'plugin_config_id' : '',
      data.vars?.length ? '' : 'vars',
    ]);
  }

  if (Object.keys(redirect).length) {
    data.plugins = {
      ...data.plugins,
      redirect,
    };
  }

  return pick(data, [
    'name',
    'desc',
    'priority',
    'methods',
    'redirect',
    'plugins',
    'labels',
    'enable_websocket',
    data.uri ? 'uri' : 'uris',
    data.vars?.length ? 'vars' : '',
    service_id.length !== 0 ? 'service_id' : '',
    data.hosts?.filter(Boolean).length !== 0 ? 'hosts' : '',
    data.remote_addrs?.filter(Boolean).length !== 0 ? 'remote_addrs' : '',
    data.host ? 'host' : '',
    data.remote_addr ? 'remote_addr' : '',
  ]);
};

const transformVarsToRules = (data: RouteModule.VarTuple[] = []): RouteModule.MatchingRule[] =>
  data.map((varTuple) => {
    const key = varTuple[0];
    const reverse = varTuple[1] === '!';
    const operator = varTuple[1] === '!' ? varTuple[2] : varTuple[1];
    const value = varTuple[varTuple.length - 1];

    let position: string;
    let name: string;
    const regex = new RegExp('^(cookie|http|arg|post_arg)_.+');
    if (regex.test(key)) {
      [, position, name] = key.split(/^(cookie|http|arg|post_arg)_/);
    } else {
      position = 'buildin';
      name = key;
    }
    return {
      position: position as RouteModule.VarPosition,
      name,
      value: typeof value === 'object' ? JSON.stringify(value) : value,
      reverse,
      operator,
      key: Math.random().toString(36).slice(2),
    };
  });

export const transformUpstreamNodes = (
  nodes: Record<string, number> = {},
): RouteModule.UpstreamHost[] => {
  const data: RouteModule.UpstreamHost[] = [];
  Object.entries(nodes).forEach(([k, v]) => {
    const [host, port] = k.split(':');
    data.push({ host, port: Number(port), weight: Number(v) });
  });
  if (data.length === 0) {
    data.push({} as RouteModule.UpstreamHost);
  }
  return data;
};

// Transform response's data
export const transformRouteData = (data: RouteModule.Body) => {
  const {
    name,
    id,
    desc,
    labels = {},
    methods = [],
    uris,
    uri,
    hosts,
    host,
    remote_addrs,
    remote_addr,
    vars = [],
    status,
    upstream,
    upstream_id,
    service_id = '',
    priority = 0,
    enable_websocket,
  } = data;

  const form1Data: Partial<RouteModule.Form1Data> = {
    name,
    id,
    desc,
    status,
    hosts: hosts || (host && [host]) || [''],
    uris: uris || (uri && [uri]) || [],
    remote_addrs: remote_addrs || (remote_addr && [remote_addr]) || [''],
    // NOTE: API_VERSION is a system label
    custom_version_label: labels.API_VERSION || '',
    custom_normal_labels: Object.keys(labels)
      .filter((item) => item !== 'API_VERSION')
      .map((key) => `${key}:${labels[key]}`),
    // @ts-ignore
    methods: methods.length ? methods : ['ALL'],
    priority,
    enable_websocket,
    service_id,
  };

  const redirect = data.plugins?.redirect || {};
  if (redirect?.http_to_https) {
    form1Data.redirectOption = 'forceHttps';
  } else if (redirect?.uri) {
    form1Data.redirectOption = 'customRedirect';
    form1Data.ret_code = redirect?.ret_code;
    form1Data.redirectURI = redirect?.uri;
  } else {
    form1Data.redirectOption = 'disabled';
  }

  const proxyRewrite = data.plugins ? data.plugins['proxy-rewrite'] : {};
  const { proxyRewriteData, URIRewriteType, hostRewriteType } = transformProxyRewrite2Formdata(
    proxyRewrite,
  );
  form1Data.proxyRewrite = proxyRewriteData;
  form1Data.URIRewriteType = URIRewriteType;
  form1Data.hostRewriteType = hostRewriteType;

  const advancedMatchingRules: RouteModule.MatchingRule[] = transformVarsToRules(vars);

  if (upstream && Object.keys(upstream).length) {
    upstream.upstream_id = 'Custom';
  }

  const form2Data: UpstreamComponent.ResponseData = convertToFormData(upstream) || {
    upstream_id: upstream_id || 'None',
  };

  const { plugins, script, plugin_config_id = '' } = data;

  const step3Data: RouteModule.Step3Data = {
    plugins,
    script,
    plugin_config_id,
  };

  return {
    form1Data,
    form2Data,
    step3Data,
    advancedMatchingRules,
  };
};
