// 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.
package com.cloud.api.query.dao;

import java.util.List;


import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;

import org.apache.cloudstack.api.response.UserResponse;

import com.cloud.api.query.vo.UserAccountJoinVO;
import com.cloud.user.User;
import com.cloud.user.UserAccount;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;

@Component
public class UserAccountJoinDaoImpl extends GenericDaoBase<UserAccountJoinVO, Long> implements UserAccountJoinDao {
    public static final Logger s_logger = Logger.getLogger(UserAccountJoinDaoImpl.class);

    private SearchBuilder<UserAccountJoinVO> vrIdSearch;

    private SearchBuilder<UserAccountJoinVO> vrAcctIdSearch;

    protected UserAccountJoinDaoImpl() {

        vrIdSearch = createSearchBuilder();
        vrIdSearch.and("id", vrIdSearch.entity().getId(), SearchCriteria.Op.EQ);
        vrIdSearch.done();

        vrAcctIdSearch = createSearchBuilder();
        vrAcctIdSearch.and("accountId", vrAcctIdSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
        vrAcctIdSearch.done();

        this._count = "select count(distinct id) from user_view WHERE ";
    }

    @Override
    public UserResponse newUserResponse(UserAccountJoinVO usr) {
        UserResponse userResponse = new UserResponse();
        userResponse.setAccountId(usr.getAccountUuid());
        userResponse.setAccountName(usr.getAccountName());
        userResponse.setAccountType(usr.getAccountType());
        userResponse.setUserSource(usr.getSource());
        userResponse.setCreated(usr.getCreated());
        userResponse.setDomainId(usr.getDomainUuid());
        userResponse.setDomainName(usr.getDomainName());
        userResponse.setEmail(usr.getEmail());
        userResponse.setFirstname(usr.getFirstname());
        userResponse.setId(usr.getUuid());
        userResponse.setLastname(usr.getLastname());
        userResponse.setState(usr.getState().toString());
        userResponse.setTimezone(usr.getTimezone());
        userResponse.setUsername(usr.getUsername());
        userResponse.setApiKey(usr.getApiKey());
        userResponse.setSecretKey(usr.getSecretKey());
        userResponse.setIsDefault(usr.isDefault());

        // set async job
        if (usr.getJobId() != null) {
            userResponse.setJobId(usr.getJobUuid());
            userResponse.setJobStatus(usr.getJobStatus());
        }

        userResponse.setObjectName("user");

        return userResponse;
    }

    @Override
    public UserAccountJoinVO newUserView(User usr) {
        SearchCriteria<UserAccountJoinVO> sc = vrIdSearch.create();
        sc.setParameters("id", usr.getId());
        List<UserAccountJoinVO> users = searchIncludingRemoved(sc, null, null, false);
        assert users != null && users.size() == 1 : "No user found for user id " + usr.getId();
        return users.get(0);
    }

    @Override
    public UserAccountJoinVO newUserView(UserAccount usr) {
        SearchCriteria<UserAccountJoinVO> sc = vrIdSearch.create();
        sc.setParameters("id", usr.getId());
        List<UserAccountJoinVO> users = searchIncludingRemoved(sc, null, null, false);
        assert users != null && users.size() == 1 : "No user found for user id " + usr.getId();
        return users.get(0);
    }

    @Override
    public List<UserAccountJoinVO> searchByAccountId(Long accountId) {
        SearchCriteria<UserAccountJoinVO> sc = vrAcctIdSearch.create();
        sc.setParameters("accountId", accountId);
        return search(sc, null, null, false);
    }

}
