// Licensed 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 React from 'react';
import FauxtonAPI from '../../../core/api';
import {ReplicationSource} from './source';
import {ReplicationTarget} from './target';
import {ReplicationOptions} from './options';
import {ReplicationSubmit} from './submit';
import {ReplicationAuth} from './auth-options';
import AuthAPI from '../../auth/api';
import Constants from '../constants';
import {ConflictModal} from './modals';
import {isEmpty} from 'lodash';

export default class NewReplicationController extends React.Component {
  constructor (props) {
    super(props);
    this.submit = this.submit.bind(this);
    this.checkAuth = this.checkAuth.bind(this);
    this.runReplicationChecks = this.runReplicationChecks.bind(this);
  }

  checkAuth () {
    this.props.hideConflictModal();
    const { replicationSource, replicationTarget,
      sourceAuthType, targetAuthType, sourceAuth, targetAuth } = this.props;

    const isLocalSource = replicationSource === Constants.REPLICATION_SOURCE.LOCAL;
    const isLocalTarget = replicationTarget === Constants.REPLICATION_TARGET.EXISTING_LOCAL_DATABASE ||
      replicationTarget === Constants.REPLICATION_TARGET.NEW_LOCAL_DATABASE;

    // Ask user to select an auth method for local source/target when one is not selected
    // and not on admin party
    if (!FauxtonAPI.session.isAdminParty()) {
      if (isLocalSource && sourceAuthType === Constants.REPLICATION_AUTH_METHOD.NO_AUTH) {
        FauxtonAPI.addNotification({
          msg: 'Missing credentials for local source database.',
          type: 'error',
          clear: true
        });
        return;
      }
      if (isLocalTarget && targetAuthType === Constants.REPLICATION_AUTH_METHOD.NO_AUTH) {
        FauxtonAPI.addNotification({
          msg: 'Missing credentials for local target database.',
          type: 'error',
          clear: true
        });
        return;
      }
    }

    this.checkLocalAccountCredentials(sourceAuthType, sourceAuth, 'source', isLocalSource).then(() => {
      this.checkLocalAccountCredentials(targetAuthType, targetAuth, 'target', isLocalTarget).then(() => {
        this.submit();
      }, () => {});
    }, () => {});
  }

  checkLocalAccountCredentials(authType, auth, label, isLocal) {
    // Skip check if it's a remote tb or not using BASIC auth
    if (authType !== Constants.REPLICATION_AUTH_METHOD.BASIC || !isLocal) {
      return FauxtonAPI.Promise.resolve(true);
    }

    if (!auth.username || !auth.password) {
      const err = `Missing ${label} credentials.`;
      FauxtonAPI.addNotification({
        msg: err,
        type: 'error',
        clear: true
      });
      return FauxtonAPI.Promise.reject(new Error(err));
    }

    return AuthAPI.login({
      name: auth.username,
      password: auth.password
    }).then((resp) => {
      if (resp.error) {
        throw (resp);
      }
      return true;
    }).catch(err => {
      FauxtonAPI.addNotification({
        msg: `Your username or password for ${label} database is incorrect.`,
        type: 'error',
        clear: true
      });
      throw err;
    });
  }

  checkReplicationDocID () {
    const {showConflictModal, replicationDocName, checkReplicationDocID} = this.props;
    checkReplicationDocID(replicationDocName).then(existingDoc => {
      if (existingDoc) {
        showConflictModal();
        return;
      }

      this.checkAuth();
    });
  }

  runReplicationChecks () {
    const {replicationDocName} = this.props;
    if (!this.checkSourceTargetDatabases()) {
      return;
    }
    if (replicationDocName) {
      this.checkReplicationDocID();
      return;
    }

    this.checkAuth();
  }

  checkSourceTargetDatabases () {
    const {
      remoteTarget,
      remoteSource,
      replicationTarget,
      localTarget,
      localSource,
      databases
    } = this.props;

    if (replicationTarget === Constants.REPLICATION_TARGET.NEW_LOCAL_DATABASE && _.includes(databases, localTarget)) {
      FauxtonAPI.addNotification({
        msg: 'The <code>' + localTarget + '</code> database already exists locally. Please enter another database name.',
        type: 'error',
        escape: false,
        clear: true
      });
      return false;
    }
    if (replicationTarget === Constants.REPLICATION_TARGET.NEW_LOCAL_DATABASE ||
        replicationTarget === Constants.REPLICATION_TARGET.NEW_REMOTE_DATABASE) {
      let error = '';
      if (/\s/.test(localTarget)) {
        error = 'The target database may not contain any spaces.';
      } else if (/^_/.test(localTarget)) {
        error = 'The target database may not start with an underscore.';
      }

      if (error) {
        FauxtonAPI.addNotification({
          msg: error,
          type: 'error',
          escape: false,
          clear: true
        });
        return false;
      }
    }

    //check if remote source/target URL is valid
    if (!isEmpty(remoteSource)) {
      let errorMessage = '';
      try {
        const url = new URL(remoteSource);
        if (url.pathname.slice(1) === '') {
          errorMessage = 'Invalid source database URL. Database name is missing.';
        }
      } catch (err) {
        errorMessage = 'Invalid source database URL.';
      }
      if (errorMessage) {
        FauxtonAPI.addNotification({
          msg: errorMessage,
          type: 'error',
          escape: false,
          clear: true
        });
        return false;
      }
    }
    if (!isEmpty(remoteTarget)) {
      let errorMessage = '';
      try {
        const url = new URL(remoteTarget);
        if (url.pathname.slice(1) === '') {
          errorMessage = 'Invalid target database URL. Database name is missing.';
        }
      } catch (err) {
        errorMessage = 'Invalid target database URL.';
      }
      if (errorMessage) {
        FauxtonAPI.addNotification({
          msg: errorMessage,
          type: 'error',
          escape: false,
          clear: true
        });
        return false;
      }
    }

    //check that source and target are not the same. They can trigger a false positive if they are ""
    if ((remoteTarget === remoteSource && !isEmpty(remoteTarget))
        || (localSource === localTarget && !isEmpty(localSource))) {
      FauxtonAPI.addNotification({
        msg: 'Cannot replicate a database to itself',
        type: 'error',
        escape: false,
        clear: true
      });

      return false;
    }

    return true;
  }

  submit () {
    const {
      replicationTarget,
      replicationSource,
      replicationType,
      replicationDocName,
      remoteTarget,
      remoteSource,
      localTarget,
      localSource,
      sourceAuthType,
      sourceAuth,
      targetAuthType,
      targetAuth
    } = this.props;

    let _rev;
    if (replicationDocName) {
      const doc = this.props.docs.find(doc => doc._id === replicationDocName);
      if (doc) {
        _rev = doc._rev;
      }
    }

    this.props.replicate({
      replicationTarget,
      replicationSource,
      replicationType,
      replicationDocName,
      localTarget,
      localSource,
      remoteTarget,
      remoteSource,
      _rev,
      sourceAuthType,
      sourceAuth,
      targetAuthType,
      targetAuth
    });
  }

  confirmButtonEnabled () {
    const {
      remoteSource,
      localSourceKnown,
      replicationSource,
      replicationTarget,
      localTargetKnown,
      localTarget,
      submittedNoChange,
    } = this.props;

    if (submittedNoChange) {
      return false;
    }

    if (!replicationSource || !replicationTarget) {
      return false;
    }

    if (replicationSource === Constants.REPLICATION_SOURCE.LOCAL && !localSourceKnown) {
      return false;
    }
    if (replicationTarget === Constants.REPLICATION_TARGET.EXISTING_LOCAL_DATABASE && !localTargetKnown) {
      return false;
    }

    if (replicationTarget === Constants.REPLICATION_TARGET.NEW_LOCAL_DATABASE && !localTarget) {
      return false;
    }

    if (replicationSource === Constants.REPLICATION_SOURCE.REMOTE && remoteSource === "") {
      return false;
    }

    return true;
  }

  render () {
    const {
      replicationSource,
      replicationTarget,
      replicationType,
      replicationDocName,
      conflictModalVisible,
      databases,
      localSource,
      remoteSource,
      remoteTarget,
      localTarget,
      updateFormField,
      clearReplicationForm,
      sourceAuthType,
      sourceAuth,
      targetAuthType,
      targetAuth
    } = this.props;

    return (
      <div style={ {paddingBottom: 20} }>
        <ReplicationSource
          replicationSource={replicationSource}
          localSource={localSource}
          databases={databases}
          remoteSource={remoteSource}
          onSourceSelect={updateFormField('replicationSource')}
          onRemoteSourceChange={updateFormField('remoteSource')}
          onLocalSourceChange={updateFormField('localSource')}
        />
        <ReplicationAuth
          credentials={sourceAuth}
          authType={sourceAuthType}
          onChangeAuthType={updateFormField('sourceAuthType')}
          onChangeAuth={updateFormField('sourceAuth')}
          authId={'replication-source-auth'}
        />
        <hr className="replication__seperator" size="1"/>
        <ReplicationTarget
          replicationTarget={replicationTarget}
          onTargetChange={updateFormField('replicationTarget')}
          databases={databases}
          localTarget={localTarget}
          remoteTarget={remoteTarget}
          onRemoteTargetChange={updateFormField('remoteTarget')}
          onLocalTargetChange={updateFormField('localTarget')}
        />
        <ReplicationAuth
          credentials={targetAuth}
          authType={targetAuthType}
          onChangeAuthType={updateFormField('targetAuthType')}
          onChangeAuth={updateFormField('targetAuth')}
          authId={'replication-target-auth'}
        />
        <hr className="replication__seperator" size="1"/>
        <ReplicationOptions
          replicationType={replicationType}
          replicationDocName={replicationDocName}
          onDocChange={updateFormField('replicationDocName')}
          onTypeChange={updateFormField('replicationType')}
        />
        <ReplicationSubmit
          disabled={!this.confirmButtonEnabled()}
          onClick={this.runReplicationChecks}
          onClear={clearReplicationForm}
        />
        <ConflictModal
          visible={conflictModalVisible}
          onClick={this.checkAuth}
          onClose={this.props.hideConflictModal}
          docId={replicationDocName}
        />
      </div>
    );
  }
}
