/*
 *  Copyright 2019-2020 Zheng Jie
 *
 *  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.
 */
package me.zhengjie;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import java.util.List;
import java.util.Optional;
import java.util.function.Function;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.ApplicationPidFileWriter;
import org.springframework.context.annotation.Bean;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import org.springframework.data.repository.query.FluentQuery.FetchableFluentQuery;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RestController;

import com.alipay.api.domain.Goods;

import io.swagger.annotations.Api;
import lombok.RequiredArgsConstructor;
import me.zhengjie.annotation.rest.AnonymousGetMapping;
import me.zhengjie.mapper.db1.IStoreMapper;
import me.zhengjie.mapper.db2.IStoreMapper2;
import me.zhengjie.modules.goods.repository.GoodsRepository;
import me.zhengjie.utils.SpringContextHolder;

/**
 * 开启审计功能 -> @EnableJpaAuditing
 *
 * @author Zheng Jie
 * @date 2018/11/15 9:20:19
 */
@EnableAsync
@RestController
@Api(hidden = true)
@SpringBootApplication
// @EnableTransactionManagement
// @EnableJpaAuditing(auditorAwareRef = "auditorAware")
@RequiredArgsConstructor
@Component
public class AppRun {

    public static void main(String[] args) {
        SpringApplication springApplication = new SpringApplication(AppRun.class);
        // 监控应用的PID，启动时可指定PID路径：--spring.pid.file=/home/eladmin/app.pid
        // 或者在 application.yml 添加文件路径，方便 kill，kill `cat /home/eladmin/app.pid`
        springApplication.addListeners(new ApplicationPidFileWriter());
        springApplication.run(args);
    }

    @Bean
    public SpringContextHolder springContextHolder() {
        return new SpringContextHolder();
    }

    private final IStoreMapper iStoreMapper;
    private final IStoreMapper2 iStoreMapper2;

    /**
     * 访问首页提示
     *
     * @return /
     */
    @AnonymousGetMapping("/")
    @Transactional
    public String index() {
        System.out.println(iStoreMapper.findByName("店1"));
        System.out.println(iStoreMapper2.findByName("店1"));
        // test();
        return "Backend service started successfully";
    }

    // public void test() {
    // // 设置使用主数据源
    // DynamicDataSource.setCurrentLookupKey("primaryDataSource");
    // // 执行数据库操作
    // System.out.println("query start:");
    // GoodsRepository goodsRepository = new GoodsRepository() {

    // @Override
    // public List<me.zhengjie.modules.goods.domain.Goods> findAll() {
    // // TODO Auto-generated method stub
    // Goods goods = new Goods();

    // }

    // @Override
    // public List<me.zhengjie.modules.goods.domain.Goods> findAll(Sort sort) {
    // // TODO Auto-generated method stub
    // throw new UnsupportedOperationException("Unimplemented method 'findAll'");
    // }

    // @Override
    // public List<me.zhengjie.modules.goods.domain.Goods>
    // findAllById(Iterable<Integer> ids) {
    // // TODO Auto-generated method stub
    // throw new UnsupportedOperationException("Unimplemented method
    // 'findAllById'");
    // }

    // @Override
    // public <S extends me.zhengjie.modules.goods.domain.Goods> List<S>
    // saveAll(Iterable<S> entities) {
    // // TODO Auto-generated method stub
    // throw new UnsupportedOperationException("Unimplemented method 'saveAll'");
    // }

    // @Override
    // public void flush() {
    // // TODO Auto-generated method stub
    // throw new UnsupportedOperationException("Unimplemented method 'flush'");
    // }

    // @Override
    // public <S extends me.zhengjie.modules.goods.domain.Goods> S saveAndFlush(S
    // entity) {
    // // TODO Auto-generated method stub
    // throw new UnsupportedOperationException("Unimplemented method
    // 'saveAndFlush'");
    // }

    // @Override
    // public <S extends me.zhengjie.modules.goods.domain.Goods> List<S>
    // saveAllAndFlush(Iterable<S> entities) {
    // // TODO Auto-generated method stub
    // throw new UnsupportedOperationException("Unimplemented method
    // 'saveAllAndFlush'");
    // }

    // @Override
    // public void deleteAllInBatch(Iterable<me.zhengjie.modules.goods.domain.Goods>
    // entities) {
    // // TODO Auto-generated method stub
    // throw new UnsupportedOperationException("Unimplemented method
    // 'deleteAllInBatch'");
    // }

    // @Override
    // public void deleteAllByIdInBatch(Iterable<Integer> ids) {
    // // TODO Auto-generated method stub
    // throw new UnsupportedOperationException("Unimplemented method
    // 'deleteAllByIdInBatch'");
    // }

    // @Override
    // public void deleteAllInBatch() {
    // // TODO Auto-generated method stub
    // throw new UnsupportedOperationException("Unimplemented method
    // 'deleteAllInBatch'");
    // }

    // @Override
    // public me.zhengjie.modules.goods.domain.Goods getOne(Integer id) {
    // // TODO Auto-generated method stub
    // throw new UnsupportedOperationException("Unimplemented method 'getOne'");
    // }

    // @Override
    // public me.zhengjie.modules.goods.domain.Goods getById(Integer id) {
    // // TODO Auto-generated method stub
    // throw new UnsupportedOperationException("Unimplemented method 'getById'");
    // }

    // @Override
    // public <S extends me.zhengjie.modules.goods.domain.Goods> List<S>
    // findAll(Example<S> example) {
    // // TODO Auto-generated method stub
    // throw new UnsupportedOperationException("Unimplemented method 'findAll'");
    // }

    // @Override
    // public <S extends me.zhengjie.modules.goods.domain.Goods> List<S>
    // findAll(Example<S> example, Sort sort) {
    // // TODO Auto-generated method stub
    // throw new UnsupportedOperationException("Unimplemented method 'findAll'");
    // }

    // @Override
    // public Page<me.zhengjie.modules.goods.domain.Goods> findAll(Pageable
    // pageable) {
    // // TODO Auto-generated method stub
    // throw new UnsupportedOperationException("Unimplemented method 'findAll'");
    // }

    // @Override
    // public <S extends me.zhengjie.modules.goods.domain.Goods> S save(S entity) {
    // // TODO Auto-generated method stub
    // throw new UnsupportedOperationException("Unimplemented method 'save'");
    // }

    // @Override
    // public Optional<me.zhengjie.modules.goods.domain.Goods> findById(Integer id)
    // {
    // // TODO Auto-generated method stub
    // throw new UnsupportedOperationException("Unimplemented method 'findById'");
    // }

    // @Override
    // public boolean existsById(Integer id) {
    // // TODO Auto-generated method stub
    // throw new UnsupportedOperationException("Unimplemented method 'existsById'");
    // }

    // @Override
    // public long count() {
    // // TODO Auto-generated method stub
    // throw new UnsupportedOperationException("Unimplemented method 'count'");
    // }

    // @Override
    // public void deleteById(Integer id) {
    // // TODO Auto-generated method stub
    // throw new UnsupportedOperationException("Unimplemented method 'deleteById'");
    // }

    // @Override
    // public void delete(me.zhengjie.modules.goods.domain.Goods entity) {
    // // TODO Auto-generated method stub
    // throw new UnsupportedOperationException("Unimplemented method 'delete'");
    // }

    // @Override
    // public void deleteAllById(Iterable<? extends Integer> ids) {
    // // TODO Auto-generated method stub
    // throw new UnsupportedOperationException("Unimplemented method
    // 'deleteAllById'");
    // }

    // @Override
    // public void deleteAll(Iterable<? extends
    // me.zhengjie.modules.goods.domain.Goods> entities) {
    // // TODO Auto-generated method stub
    // throw new UnsupportedOperationException("Unimplemented method 'deleteAll'");
    // }

    // @Override
    // public void deleteAll() {
    // // TODO Auto-generated method stub
    // throw new UnsupportedOperationException("Unimplemented method 'deleteAll'");
    // }

    // @Override
    // public <S extends me.zhengjie.modules.goods.domain.Goods> Optional<S>
    // findOne(Example<S> example) {
    // // TODO Auto-generated method stub
    // throw new UnsupportedOperationException("Unimplemented method 'findOne'");
    // }

    // @Override
    // public <S extends me.zhengjie.modules.goods.domain.Goods> Page<S>
    // findAll(Example<S> example,
    // Pageable pageable) {
    // // TODO Auto-generated method stub
    // throw new UnsupportedOperationException("Unimplemented method 'findAll'");
    // }

    // @Override
    // public <S extends me.zhengjie.modules.goods.domain.Goods> long
    // count(Example<S> example) {
    // // TODO Auto-generated method stub
    // throw new UnsupportedOperationException("Unimplemented method 'count'");
    // }

    // @Override
    // public <S extends me.zhengjie.modules.goods.domain.Goods> boolean
    // exists(Example<S> example) {
    // // TODO Auto-generated method stub
    // throw new UnsupportedOperationException("Unimplemented method 'exists'");
    // }

    // @Override
    // public <S extends me.zhengjie.modules.goods.domain.Goods, R> R
    // findBy(Example<S> example,
    // Function<FetchableFluentQuery<S>, R> queryFunction) {
    // // TODO Auto-generated method stub
    // throw new UnsupportedOperationException("Unimplemented method 'findBy'");
    // }

    // @Override
    // public Optional<me.zhengjie.modules.goods.domain.Goods> findOne(
    // Specification<me.zhengjie.modules.goods.domain.Goods> spec) {
    // // TODO Auto-generated method stub
    // throw new UnsupportedOperationException("Unimplemented method 'findOne'");
    // }

    // @Override
    // public List<me.zhengjie.modules.goods.domain.Goods> findAll(
    // Specification<me.zhengjie.modules.goods.domain.Goods> spec) {
    // // TODO Auto-generated method stub
    // throw new UnsupportedOperationException("Unimplemented method 'findAll'");
    // }

    // @Override
    // public Page<me.zhengjie.modules.goods.domain.Goods> findAll(
    // Specification<me.zhengjie.modules.goods.domain.Goods> spec, Pageable
    // pageable) {
    // // TODO Auto-generated method stub
    // throw new UnsupportedOperationException("Unimplemented method 'findAll'");
    // }

    // @Override
    // public List<me.zhengjie.modules.goods.domain.Goods> findAll(
    // Specification<me.zhengjie.modules.goods.domain.Goods> spec, Sort sort) {
    // // TODO Auto-generated method stub
    // throw new UnsupportedOperationException("Unimplemented method 'findAll'");
    // }

    // @Override
    // public long count(Specification<me.zhengjie.modules.goods.domain.Goods> spec)
    // {
    // // TODO Auto-generated method stub
    // throw new UnsupportedOperationException("Unimplemented method 'count'");
    // }

    // };
    // System.out.println("query end:");
    // // ...
    // // 清除数据源上下文
    // DynamicDataSource.clearCurrentLookupKey();

    // // 设置使用辅数据源
    // DynamicDataSource.setCurrentLookupKey("secondDataSource");
    // // 执行数据库操作
    // System.out.println("query2 start:");
    // System.out.println("query2 end:");
    // // ...
    // // 清除数据源上下文
    // DynamicDataSource.clearCurrentLookupKey();
    // }
}
