/** \file fsindex.cpp .
-----------------------------------------------------------------------------


 * 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.

-----------------------------------------------------------------------------

   Description:

-----------------------------------------------------------------------------


-------------------------------------------------------------------------- */


/* ----------------------------------------------------------------------- */
/*       Include dependencies                                              */
/* ----------------------------------------------------------------------- */

#include "uima/fsindex.hpp"
#include "uima/msg.h"
#include "uima/internal_fspromoter.hpp"
#include "uima/lowlevel_fsfilter.hpp"
#include "uima/lowlevel_index.hpp"
#include "uima/lowlevel_indexrepository.hpp"
#include "uima/fsfilterbuilder.hpp"

using namespace uima::internal;
/* ----------------------------------------------------------------------- */
/*       Constants                                                         */
/* ----------------------------------------------------------------------- */

/* ----------------------------------------------------------------------- */
/*       Forward declarations                                              */
/* ----------------------------------------------------------------------- */

/* ----------------------------------------------------------------------- */
/*       Types / Classes                                                   */
/* ----------------------------------------------------------------------- */

/* ----------------------------------------------------------------------- */
/*       Implementation                                                    */
/* ----------------------------------------------------------------------- */

/*
Those implementations are thin wrappers on top of the lowlevel API.
*/

namespace uima {

  UIMA_EXC_CLASSIMPLEMENT(InvalidIndexObjectException, CASException);
  UIMA_EXC_CLASSIMPLEMENT(WrongFSTypeForIndexException, CASException);

  void FSIndex::checkValidity() const {
    if (!isValid()) {
      UIMA_EXC_THROW_NEW(InvalidIndexObjectException,
                         UIMA_ERR_INVALID_INDEX_OBJECT,
                         UIMA_MSG_ID_EXC_INVALID_INDEX_OBJECT,
                         ErrorMessage(UIMA_MSG_ID_EXCON_UNKNOWN_CONTEXT),
                         ErrorInfo::recoverable
                        );
    }
  }

  FSIndex::FSIndex(lowlevel::IndexABase const * anIndex, lowlevel::IndexRepository const & rFSSystem)
      : iv_pIndex(anIndex),
      iv_indexRepository(& CONST_CAST(uima::lowlevel::IndexRepository &, rFSSystem) ) {}

  FSIndex::FSIndex(lowlevel::IndexABase const * anIndex, lowlevel::IndexRepository & rFSSystem)
      : iv_pIndex(anIndex),
      iv_indexRepository(& rFSSystem) {}

  FSIndex::FSIndex()
      : iv_pIndex(NULL),
      iv_indexRepository(NULL) {}

  bool FSIndex::isValid() const {
    return(iv_pIndex != NULL) && (iv_indexRepository != NULL);
  }

  size_t FSIndex::getSize() const {
    checkValidity();
    return iv_pIndex->getSize();
  }

  FeatureStructure FSIndex::find(FeatureStructure const & anFS) const {
    checkValidity();
    if (!anFS.isValid()) {
      UIMA_EXC_THROW_NEW(InvalidFSObjectException,
                         UIMA_ERR_INVALID_FS_OBJECT,
                         UIMA_MSG_ID_EXC_INVALID_FS_OBJECT,
                         ErrorMessage(UIMA_MSG_ID_EXCON_FINDING_FS_IN_INDEX),
                         ErrorInfo::recoverable
                        );
    }
    lowlevel::TyFS result = iv_pIndex->find( internal::FSPromoter::demoteFS( anFS ) );
    return internal::FSPromoter::promoteFS( result, iv_indexRepository->getCas() );
  }

  FSIterator FSIndex::iterator() const {
    checkValidity();
    lowlevel::IndexIterator* it = iv_pIndex->createIterator();
    return FSIterator( it, &iv_indexRepository->getCas() );
  }


  FSIterator FSIndex::typeSetIterator(set<uima::Type> const & crTypes) const {
    checkValidity();
    uima::lowlevel::TyFSType tyIndexType = iv_pIndex->getType();
    set<uima::lowlevel::TyFSType> setLowlevelTypes;
    set<uima::Type>::const_iterator cit;
    for (cit = crTypes.begin(); cit != crTypes.end(); ++cit) {
      uima::lowlevel::TyFSType tyType = uima::internal::FSPromoter::demoteType(*cit);
      if ( ! iv_indexRepository->getFSHeap().getTypeSystem().subsumes(tyIndexType, tyType) ) {
        UIMA_EXC_THROW_NEW(WrongFSTypeForIndexException,
                           UIMA_ERR_WRONG_FSTYPE_FOR_INDEX,
                           UIMA_MSG_ID_EXC_WRONG_FSTYPE_FOR_INDEX,
                           ErrorMessage(UIMA_MSG_ID_EXCON_CREATING_ITERATOR),
                           ErrorInfo::recoverable
                          );

      }
      setLowlevelTypes.insert(tyType);
    }

    uima::lowlevel::IndexIterator * it = iv_pIndex->createTypeSetIterator( setLowlevelTypes );
    return FSIterator( it, &iv_indexRepository->getCas() );
  }



///////////////////////////////////////////////////////////////

  /**
   * This class wraps an OO API filter to obey the lowlevel::FSFilter interface.
   */
  namespace internal {
    class FSFilterWrapper : public lowlevel::FSFilter {
    private:
      uima::FSFilter const * iv_cpFilter;
      uima::CAS const * iv_cas;
    public:
      FSFilterWrapper(uima::FSFilter const * cpFilter, uima::CAS const * cas)
          : iv_cpFilter(cpFilter),
          iv_cas(cas) {
        assert(EXISTS(iv_cpFilter));
        assert(EXISTS(iv_cas));
      }

      bool isFiltered(lowlevel::TyFS anFS) const {
        assert(EXISTS(iv_cpFilter));
        assert(EXISTS(iv_cas));
        // const cast is OK here since anFS will not be changed
        //  since it is passed as const parameters to isFiltered
        FeatureStructure fs = internal::FSPromoter::promoteFS(anFS, *iv_cas);
        return iv_cpFilter->isFiltered(fs);
      }
    };
  }


  FSIterator FSIndex::filteredIterator(uima::FSFilter const * cpFilter) const {
    checkValidity();
    internal::FSFilterWrapper* pFilterWrapper = new internal::FSFilterWrapper( cpFilter, & iv_indexRepository->getCas() );
    lowlevel::IndexIterator* it = iv_pIndex->createFilteredIterator(pFilterWrapper);
    return FSIterator(it, & iv_indexRepository->getCas() );
  }

}


