/*-
 * ============LICENSE_START=======================================================
 * OSAM
 * ================================================================================
 * Copyright (C) 2018 AT&T
 * ================================================================================
 * 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.
 * ============LICENSE_END=========================================================
 */
package org.onap.osam.job.repository.job;

import org.onap.osam.job.dao.job.JobStatus;
import org.onap.osam.job.dao.job.OsamJob;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.UUID;

public interface OsamJobRepository extends CrudRepository<OsamJob, Long> {



    Optional<OsamJob> findByUuid(UUID uuid);

    List<OsamJob> findAllByUuid(Iterable<UUID> uuids);

    //TODO Pavel add intervalCondition to the query
    //String intervalCondition = (topic==JobStatus.CREATING) ? "" : (" and MODIFIED_DATE <= '" + nowMinusInterval()+"'");
    //@Query("select o from OsamJob o where o.status = :status and o.takenBy is null and o.deletedAt is null order by o.modifiedDate asc")
    //List<OsamJob> queryFirst1ByStatusAndTakenByIsNullAndDeleteAtIsNullOrderByModifiedDateAsc(@Param("status") JobStatus status);
    List<OsamJob> queryFirst1ByStatusAndTakenByIsNullAndDeletedAtIsNullOrderByModifiedDateAsc(@Param("status") JobStatus status);

    //Updates

    @Transactional
    @Modifying
    @Query("update OsamJob job set job.takenBy = :takenBy where job.uuid = :uuid and job.age = :age and job.takenBy is null")
    Integer updateOsamCoreJobsAge(@Param("takenBy") String takenBy, @Param("uuid") UUID uuid, @Param("age") Integer age);

    @Transactional
    @Modifying
    @Query("update OsamJob job set job.deletedAt = :now where job.uuid = :uuid and job.status in(:pending, :stopped) and job.takenBy is null")
    Integer updateOsamCoreJobToBeDeleted(@Param("now") Date date, @Param("uuid") UUID uuid, @Param("pending") String pending, @Param("stopped") String stopped);

    @Transactional
    @Modifying
    @Query("update OsamJob job set job.status = concat(':prefix_',job.status), job.takenBy = null where job.uuid = :uuid and job.status not like ':prefix_%'")
    Integer muteOsamCoreJob(@Param("uuid") UUID uuid, @Param("")String prefix);

}
